题目:小兵向前冲
题目描述:N*M的棋盘上,小兵要从左下角走到右上角,只能向上或则向右走,问由多少种走法。
- 套路:计数问题
- 暴力搜索(回溯法)
- F(n,m)表示棋盘大小为n*m时走法数量
-
#include <iostream>
using namespace std;
int forward(int n, int m)
{
if (n == 0 || m == 0)
{ //棋盘都没有走啥?
return 0;
}
if (n == 1 || m == 1) //条状棋盘
{
return 1;
}
return forward(n, m - 1) + forward(n - 1, m); //4*4 <-- 4*3 || 3*4
}
int main()
{
cout<<forward(2,3);
return 0;
}
要是小兵可以走两步呢?
修改代码:
return forward(n, m - 1) + forward(n - 1, m) +
forward(n, m - 2) + forward(n - 2, m);
//4*4 <-- 4*3 || 3*4 || 4*2 ||2*4
拓展
组合数的递推公式
#include <iostream>
using namespace std;
int nCr(int n, int m) //组合数
{
if(n < m){
return 0;
}
if (m == 0)
{
return 1;
}
return nCr(n-1,m-1) + nCr(n-1,m);
}
int main()
{
cout << nCr(3,2);
return 0;
}
可以类比于棋盘,只可以往右上角走或者往上走,问有多种解法。这就是组合数的物理意义。要是(n,m)这个格子不能走呢?那直接让 。