动态规划笔记(二)

题目:小兵向前冲
题目描述:N*M的棋盘上,小兵要从左下角走到右上角,只能向上或则向右走,问由多少种走法。

  • 套路:计数问题
    • 暴力搜索(回溯法)
    • F(n,m)表示棋盘大小为n*m时走法数量
    • F ( n , m ) = F ( n , m 1 ) + F ( n 1 , m )   i f   n m > 0 , o t h e r w i s e   F ( n , m ) = 1 F(n,m) = F(n,m-1) + F(n-1,m) ~if ~n*m >0,otherwise~ F(n,m) = 1
    • f o r    i <    2    t o   n for~~i<-~ ~2~~ to~n
      • f o r    j <    2    t o    m for~~ j<-~~2 ~~to ~~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

拓展

组合数的递推公式
C ( n , m ) = C ( n 1 , m 1 ) + C ( n 1 , m ) C(n,m) = C(n-1,m-1) + C(n-1,m)

#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)这个格子不能走呢?那直接让 F ( n , m ) = 0 F(n,m)=0

猜你喜欢

转载自blog.csdn.net/qq_39504764/article/details/89929691
今日推荐