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

将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 }
代码君

 

posted @ 2015-03-18 03:49  AOQNRMGYXLMV  阅读(229)  评论(0编辑  收藏  举报