UVa10943

10943 How do you add?
Larry is very bad at math — he usually uses a calculator, which worked
well throughout college. Unforunately, he is now struck in a deserted
island with his good buddy Ryan after a snowboarding accident.
They’re now trying to spend some time figuring out some good
problems, and Ryan will eat Larry if he cannot answer, so his fate is
up to you!
It’s a very simple problem — given a number N, how many ways
can K numbers less than N add up to N?
For example, for N = 20 and K = 2, there are 21 ways:
0+20
1+19
2+18
3+17
4+16
5+15
...
18+2
19+1
20+0
Input
Each line will contain a pair of numbers N and K. N and K will both be an integer from 1 to 100,
inclusive. The input will terminate on 2 0’s.
Output
Since Larry is only interested in the last few digits of the answer, for each pair of numbers N and K,
print a single number mod 1,000,000 on a single line.
Sample Input
20 2
20 2
0 0
Sample Output
21
21

题意:

将K个不超过N的非负整数加起来,使得它们的和为N,有多少种方法?N=5,K=2时一共有6种方法,即0+5、1+4、2+3、3+2、4+1、5+0。输出方法总数模1000000的余数。

分析:

相当于解方程sum{xi | i = 1,2,…,K && xi >= 0}。答案就是C(N+K-1,K-1)。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 #define ll long long
 6 const int MOD = 1000000;
 7 const int maxk = 200;
 8 ll C[maxk + 2][maxk + 2];
 9 // 线性算法,可以加取模
10 void get_C(){
11     memset(C,0,sizeof C);
12     C[0][0] = 1;
13     for(int i = 0 ; i <= maxk ; i++){
14         C[i][0] = C[i][i] = 1;
15         for(int j = 1 ; j < i ; j++)
16             C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
17     }
18 }
19 // 直接计算,不要随便取模,计算量过大时会有误差
20 long long cal_C(long long n,long long m){
21     double ans = 1;
22     for(int i = 0 ; i < m ; i++) ans *= n - i;
23     for(int i = 0 ; i < m ; i++) ans /= i + 1;
24     return (long long)(ans + 0.5) % MOD;
25 }
26 int main(){
27     int N,K;
28     get_C();
29     while(scanf("%d%d",&N,&K) == 2 && N){
30         printf("%lld\n",C[N + K - 1][K - 1]);
31     }
32     return 0;
33 }

时间: 2024-11-06 17:37:38

UVa10943的相关文章

uva10943(隔板法)

很裸的隔板法. 引用一下维基上对隔板法的解释: 现在有10个球,要放进3个盒子里 ●●●●●●●●●● 隔2个板子,把10个球被隔开成3个部份 ●|●|●●●●●●●●.●|●●|●●●●●●●.●|●●●|●●●●●●.●|●●●●|●●●●●.●|●●●●●|●●●●.●|●●●●●●|●●●....... 如此类推,10个球放进3个盒子的方法总数为 n个球放进k个盒子的方法总数为 问题等价于求的可行解数,其中为正整数. **如果允许有空盒子**: 现在有10个球,要放进3个盒子里,并允许空

全加和 UVa10943

1.题目描述:点击打开链接 2.解题思路:本题实际上就是求x1+x2+...+xk=n的非负整数解的个数.根据组合数学的结论,答案是C(n+k-1,k-1).可以事先预处理算出所有的组合数. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #in

uva10943 How do you add?

题意:把K个不超过N的非负整数加起来,使得它们的和为N,有多少种方法 思路: 令dp[i][j]为和为i用了j个数的方案数,那么转移就是dp[i][j]=dp[i-1][j]+dp[i][j-1] dp[i-1][j]表示在和为i-1用了j个数的方案中,最后一个数+1 dp[i][j-1]表示在和为i用了j-1个数的方案中,加上一个0 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int dp[101][101]; 5 const i

《算法竞赛入门经典——训练指南》第二章题库

UVa特别题库 UVa网站专门为本书设立的分类题库配合,方便读者提交: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=442 注意,下面注有"extra"的习题并没有在书中出现,但在上面的特别题库中有,属于附加习题. 基础练习 (Basic Problems) UVa11388 GCD LCM UVa11889 Benefit UVa10943 How do y