动态规划笔记(二)

题目:小兵向前冲
题目描述: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(n,m)=F(n,m1)+F(n1,m) if nm>0,otherwise F(n,m)=1
    • f o r    i &lt; −    2    t o   n for~~i&lt;-~ ~2~~ to~n for  i<  2  to n
      • f o r    j &lt; −    2    t o    m for~~ j&lt;-~~2 ~~to ~~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) C(n,m)=C(n1,m1)+C(n1,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 F(n,m)=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值