UVa 10943 (数学 递推) How do you add?

本文介绍了如何使用递推公式和组合数学原理,计算将K个不超过N的非负整数加起来,使得它们的和为N的不同组合方式的数量。通过将问题转化为将N个小球放入K个盒子的方法数,得出最终答案为C(N+K-1,K-1),并提供了相应的代码实现。

将K个不超过N的非负整数加起来,使它们的和为N,一共有多少种方法。

设d(i, j)表示j个不超过i的非负整数之和为i的方法数。

d(i, j) = sum{ d(k, j-1) | 0 ≤ k ≤ i },可以理解为前j-1个数之和为i-k,最后一个数为k

 

还有一种更快的递推办法,把这个问题转化为将N个小球放到K个盒子中的方法数,盒子可以为空。

就等价于求x1 + x2 +...+ xK = N的非负整数解的个数,根据组合数学的知识容易算出结果为C(N+K-1, K-1).

所以也可以这样递推:d(i, j) = d(i-1, j) + d(i, j-1)

 1 #include <cstdio>
 2 
 3 const int M = 1000000;
 4 const int maxn = 100;
 5 int d[maxn + 10][maxn + 10];
 6 
 7 int main()
 8 {
 9     for(int i = 1; i <= maxn; i++)
10         d[0][i] = 1;
11     for(int i = 1; i <= maxn; i++)
12         for(int j = 1; j <= maxn; j++)
13             d[i][j] = (d[i-1][j] + d[i][j-1]) % M;
14 
15     int n, k;
16     while(scanf("%d%d", &n, &k) == 2 && n && k) printf("%d\n", d[n][k]);
17 
18     return 0;
19 }
代码君

 

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4346134.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值