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 }