uva—How do you add?
来源:互联网 发布:waphyseccom软件下载 编辑:程序博客网 时间:2024/06/05 18:57
Problem A: 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 canK 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 numbersN and K, print a single number mod 1,000,000 on a single line.Sample Input
20 220 20 0
Sample Output
2121题意:给出两个数N,K,N代表数的大小,K代表将N拆成几个数相加,问N对K能有多少种组合?
分析:
法一:典型的递推DP,是有规律的,一开始可能想不通,可以先写出一些简单的情况加以总结。
1 1:1->1
1 2:0+1,1+0->2
1 3:0+0+1,0+1+0,1+0+0->3
2 1:2->1
2 2:0+2,1+1,2+0->3
2 3:0+0+2,0+2+0,2+0+0,0+1+1,1+0+1,1+1+0->6
3 1:3->1
3 2:0+3,1+2,2+1,3+0->4
3 3:0+0+3,0+3+0,3+0+0,0+1+2,0+2+1,1+2+0,2+1+0,1+0+2,2+0+1,1+1+1->10
由上发现好像(2 2)=(1 2)+(2 1),(2 3)=(1 3)+(2 2),(3 2)=(2 2)+(3 1),(3 3)=(2 3)+(3 2)
即:dp[N][K]=dp[N-1][K]+dp[N][K-1],我们想一下,为什么是这样呢?
用递推的思想,当你求(3 3)的时候,实际上就是(3 2)再加一位0,(2 3)在某一位上加1,依次递推下去......
因此有,dp[N][K]=dp[N-1][K]+dp[N][K-1]
void init(){ memset(dp,0,sizeof(dp)); dp[0][0]=1;//初始化!!! for(int i=1;i<101;i++)//还有i是从1开始的 { dp[0][i]=1;///(3 1)->1 for(int j=1;j<101;j++)///需要注意的是dp[j][i]的循环而不是dp[i][j],你在求(3 3)的时候保证///(2 3)和(3 2)都已经求出来了,因此应该是同一位数的先都求出来。 dp[j][i]=(dp[j][i-1]+dp[j-1][i])%MOD; }}法二:由上,我们不难想到另一种方法dp[i][j] = sum{ dp[i-1][j-t] } 表示当前这一位填p
dp[i][j] 表示i个不超过N的非负整数加起来的和为j的方法数。(刚好与上面相反dp[K][N])
void init(){ memset(dp,0,sizeof(dp)); for(int i=0;i<101;i++) dp[i][0]=1; for(int i=1;i<101;i++) for(int j=1;j<101;j++) for(int t=0;t<=j;t++) dp[i][j]=(dp[i][j]+dp[i-1][j-t])%MOD;}
法三:组合数学的思想——隔板法
关于组合排列的问题,高中经常做到。
把一个数分成几个数相加,相当于把该数大小看成球的个数N,然后将球放入K个盒子(可空)中,有几种放法。
就是要放入k-1个板 ,即C(N+K-1, K-1)
代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 102#define MOD 1000000int dp[N][N];/*void init(){ memset(dp,0,sizeof(dp)); for(int i=0;i<101;i++) dp[i][0]=1; for(int i=1;i<101;i++) for(int j=1;j<101;j++) for(int t=0;t<=j;t++) dp[i][j]=(dp[i][j]+dp[i-1][j-t])%MOD;}*/void init(){ memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1;i<101;i++) { dp[0][i]=1; for(int j=1;j<101;j++) dp[j][i]=(dp[j][i-1]+dp[j-1][i])%MOD; }}int main(){ int n,k; init(); while(scanf("%d%d",&n,&k),n&&k) cout<<dp[n][k]<<endl; return 0;}
- uva—How do you add?
- UVA 10943 How do you add?——背包
- UVA 10943 - How do you add
- UVA 10943 How do you add?
- uva 10943 - How do you add?
- UVa 10943 - How do you add?
- UVa:10943 How do you add?
- UVA 10943 - How do you add?(dp)
- uva 10943 - How do you add?(dp)
- UVA 10943 - How do you add?
- UVA 10943 How do you add?
- uva 10943 How do you add? (DP)
- UVa 10943 - How do you add?
- UVA 10943 How do you add?
- UVA - 10943 How do you add?
- UVA 10943(How do you add?)
- UVA 10943 - How do you add?
- UVA 10943 HOW do you add?
- 在iTunes中安装ipad应用程序图文详细步骤
- Android SDK下载地址
- NYOJ_32
- ubuntu安装运行mongodb
- c/c++基础(二十七) Linux下core文件调试方法
- uva—How do you add?
- 在JAVA中利用SOCKET创建一个用于收发报文的长连接服务器
- easyUI datagrid 前端假分页
- oc中的内存管理机制
- Java字符编码根本原理
- Andriod 适配器使用事例
- Perl中列用工具List模块
- 蓝牙模块如何进入AT模式
- mac下 安装python包numpy, nltk