POJ 1664 放苹果 计数问题的DP 划分数问题模板

Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1
7 3
Sample Output
8

解题思路:
定义dp[i][j] := j的i划分的总数,对应于本问题则是将j个苹果放到i个盘子中的总的分法个数
考虑j的i划分,用Ak来表示第k个盘子中的物品数量
∑ k = 1 i   A i &ThinSpace; = j \sum_{k=1}^{i}\ A_i\,=j k=1i Ai=j
1、如果对于所有的盘子,都有Ak > 0,那么从每个盘子中都拿去一个物品,就是 j-i 的 i 划分;
2、如果存在物品数为0的盘子,这便对应了j 的 i-1 划分。
得到动态规划方程如下:

if (j >= i) {//盘子数不大于物品数,两种情况都可能存在
	dp[i][j] = dp[i - 1][j] + dp[i][j - i];
}
//盘子比物品还多,则一定有空盘子
else dp[i][j] = dp[i - 1][j];

不要忘记初始化:我的理解是把0个物品放在 i 个盘子上,那么只有所有的盘子都为空这一种放法。把i个物体放在0个盘子上,则没有相应的放法。

for (int i = 1; i <= 10; i++) {//不要忘记初始化!!!
	dp[i][0] = 1; dp[0][i] = 0;
}

AC代码

#include<iostream>
using namespace std;
int dp[11][11];
int main() {
	int t, m, n;//m个苹果  n 个盘子
	cin >> t;
	for (int i = 1; i <= 10; i++) {//不要忘记初始化!!!
		dp[i][0] = 1;  dp[0][i] = 0;
	}
	for (int i = 1; i <= 10; i++) {
		for (int j = 1; j <= 10; j++) {
			if (j >= i) {
				dp[i][j] = dp[i - 1][j] + dp[i][j - i];
			}
			else dp[i][j] = dp[i - 1][j];
			//cout << i << " " << j << " " << dp[i][j] << endl;
		}
	}
	while (t--) {
		cin >> m >> n;
		cout << dp[n][m] << endl;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值