动态规划--分梨

这个问题可以使用动态规划来解决。我们可以定义一个二维数组 dp[i][j],其中 dp[i][j] 表示将 i 个梨子分配到 j 个盘子中的方法数。

首先,考虑边界情况:

  • 当梨子数 i 等于 0 时,无论有多少个盘子 j,都只有一种方法,即将所有盘子都空着。
  • 当只有一个盘子 j 时,无论有多少个梨子 i,都只有一种方法,即将所有梨子都放在这个盘子里。

然后,我们可以使用递推关系来填充 dp 数组:

  • 当梨子数 i 小于盘子数 j 时,无法进行合理的分配,此时 dp[i][j] 应该等于将 i 个梨子分配到 i 个盘子中的方法数,因为一个盘子最多只能放一个梨子,多余的盘子没有用。即 dp[i][j] = dp[i][i]
  • 当梨子数 i 大于等于盘子数 j 时,我们可以考虑两种情况:
    • 至少有一个盘子为空,这种情况下,我们将梨子分配到 j - 1 个盘子中,方法数为 dp[i][j - 1]
    • 每个盘子都至少有一个梨子,这种情况下,我们将 j 个盘子中的一个梨子拿出来,剩下的梨子分配到剩下的 j - 1 个盘子中,方法数为 dp[i - j][j]

思路清楚后,定义二维数组的时候,编译出现了问题,就是在使用 vector<vector<int>> 定义二维向量时,尝试编译器解释 >> 为右移操作符而导致的。为了解决这个问题,你可以在 >> 之间添加一个空格,改为 vector<vector<int> >,以明确告知编译器这是模板参数列表的结束标记。 

下面这个代码,之前交上去都是对的,后面再交就出现不对了,找了半天是为什么

#include <bits/stdc++.h>
using namespace std;

int main(){
	int t;
	cin>>t;
	while(t--)
	{
		int m,n;
		cin >> m >> n;
		//定义一个大小为(m+1)x(n+1)的二维数组,并将所以元素初始化为0 
		vector<vector<int> > dp(m + 1, vector<int>(n + 1, 0));
		
		//边界情况
		
		//只有一个盘子 ,j=1 
		for(int i=0;i<=m;i++)
		{
			dp[i][1]=1;
		}
		
		//梨子数为0,i=0 
		for(int j=0;j<=n;j++)
		{
			dp[0][j]=1;
		}
		
		//递归填充 ,分情况计算dp[i][j]的值
		for(int i=1;i<=m;i++)
		{
			for(int j=2;j<=n;j++)
			{
				if(i<j)
				{
					dp[i][j]=dp[i][i];
				}
				else
				{
					dp[i][j]=dp[i][j-1]+dp[i-j][j];
				}
			}
		}
		cout<<dp[m][n];	 
	}
	
	return 0;
}

原因就是输入包含多组测试样例,还差一个外循环

下面是最新更新的正确代码

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;
	while(cin >> t)
	{
		while(t--)
	    {
	        int m, n;
	        cin >> m >> n;
	        //定义一个大小为(m+1)x(n+1)的二维数组,并将所有元素初始化为0 
	        vector<vector<int> > dp(m + 1, vector<int>(n + 1, 0));
	        
	        //边界情况
	        
	        //只有一个盘子 ,j=1 
	        for(int i = 0; i <= m; i++)
	        {
	            dp[i][1] = 1;
	        }
	        
	        //梨子数为0,i=0 
	        for(int j = 0; j <= n; j++)
	        {
	            dp[0][j] = 1;
	        }
	        
	        //递归填充 ,分情况计算dp[i][j]的值
	        for(int i = 1; i <= m; i++)
	        {
	            for(int j = 2; j <= n; j++)
	            {
	                if(i < j)
	                {
	                    dp[i][j] = dp[i][j-1];
	                }
	                else
	                {
	                    dp[i][j] = dp[i][j-1] + dp[i-j][j];
	                }
	            }
	        }
	        cout << dp[m][n] << endl;
	    }
	}
    
    
    return 0;
}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值