不常见的:走格子问题

题目:

请编写一个函数(允许增加子函数),计算n x m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。

输入输出:

输入描述:      输入两个正整数n ,m

输出描述:       返回结果

题解: 

这道题从左上角到右下角,不是走格子,而是选择边缘线,这个比较特殊,我们只能尝试找一下规律。

当只有一个格子的时候(n=1,m=1)         

        

我们尝试着增加格子:

 

 

我们可已从以上的图中发现这样的一个规律:

当只有一列的时候有多少个横线就有多少种方法:横线条数为n+1,而此时m=1;所以这种情况下有n+m中方法到达右下角

只有一行的时候,情况类似,方法数也为n+m

即总结上面的两种情况   n=1或者m=1的时候,有n+m种情况

当n>1且m>1的时候,上面的规律就不太适用了。

但是我们图中发现4号位置方法数量是三号位置的方法数量和2号位置的方法数量之和:而2号方法数和3号位置方法数我们是可以计算的!

但是其他的情况适用嘛:我们来递推一下

我们用3*3的方格为例:1后位置可以有3号位置和2号位置之和。。。。。。。

有递推过程太长太复杂,我们直接看左边的图,三号位置有5号位置和4号位置计算出来,这是没问题的;

2号位置我们可以计算,前面证明过也没什么问题。

2号位置和3号位置到达1号位置各自只有一种方法。所以1号位置通过2号和3号位置计算也是没有任何问题的。

如果我们放大,递推过程没有问题!

所以

     dp(n,m)=dp(n-1,m)+dp(m-1,n);

下面我们就可以看代码了:

代码:动态规划

int Pathsum(int n, int m)
{
	if (n == 0 || m == 0)
		return 0;
	vector<vector<int>> dp(n + 1, vector<int>(m + 1));

	for (int i = 1; i<n + 1; ++i)
	{
		for (int j = 1; j<m + 1; ++j)
		{   //仅有一行或者一列的情况
			if (i == 1 || j == 1)
				dp[i][j] = i + j;
			else
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
		}
	}
	return dp[n][m];
}

 

 化简之后:空间复杂度O(m)

int Pathsum(int n, int m)
{
	if (n == 0 || m == 0)
		return 0;
	vector<int>dp(m + 1);
	int k = 1;
	while (k<n + 1)
	{
		for (int i = 1; i<m + 1; ++i)
		{
			if (k == 1 || i == 1)
				dp[i] = k + i;
			else
				dp[i] = dp[i - 1] + dp[i];

		}
		k++;
	}
	return dp[m];
}

 

递归方法: 

int Pathsum(int n,int m)
{
    if(n==0||m==0)
        return 0;
      if(n==1||m==1)
          return n+m;
      else
          return Pathsum(n-1,m)+Pathsum(n,m-1);
}


int main()
{
    int n,m;
    while(cin>>n>>m)
    cout<<Pathsum(n,m)<<endl;
    return 0;
}

本篇博文到这里就结束了,谢谢大家的观看!

你们的 【三连】 是给Qyuan最大的肯定!

↓          ↓           ↓

注:如果本篇博客有任何错误和建议,欢迎伙伴们留言,你快说句话啊!

如果需要练习的小伙伴,可以打开下方链接:

https://www.nowcoder.com/questionTerminal/e2a22f0305eb4f2f9846e7d644dba09b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值