题目:
下沙的沙子有几粒? |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 894 Accepted Submission(s): 505 |
|
Problem Description 2005年11月份,我们学校参加了ACM/ICPC 亚洲赛区成都站的比赛,在这里,我们获得了历史性的突破,尽管只是一枚铜牌,但获奖那一刻的激动,也许将永远铭刻在我们几个人的心头。借此机会,特向去年为参加ACM亚洲赛而艰苦集训了近半年的各位老队员表示感谢。
|
Input 输入数据包含多个测试实例,每个占一行,由两个整数m和n组成,m和 n 分别表示字符串中H和D的个数。由于我们目前所使用的微机和老美的超级计算机没法比,所以题目给定的数据范围是(1<=n<=m<=20)。
|
Output 对于每个测试实例,请输出下沙的沙粒到底有多少,计算规则请参考“宇春猜想”,每个实例的输出占一行。
|
Sample Input 1 13 1
|
Sample Output 13
|
Author lcy
|
Source HDU 2006-4 Programming Contest
|
Recommend lxj |
题目大意:
就是给你m个H和n个D,然后从左开始数H的累积个数总是不比D的累计数少的排列有多少种举一个测试案例吧:3个H和1个D总共有3种排列,依次是:H D H H,H H D H,H H H D三种排列,
题目分析:
简单DP。题目一开始又扯了一大堆有的没的。
。。。。。其实题目就是说“有m个H,n个D,且任意索引上H的个数都不小于D的个数,问这样的方案数有多少种”。
递推公式是: a[m][n] = a[m-1][n] + a[m][n-1] 。前面代表的是H的个数.后面代表的是D的个数。
推导过程如下:然后当n=0的时候无论m取何值都是1,递推公式怎么推来的呢?我现在说下我的思路吧!假设3个H和2个D是由2个H和2个D还有3个H一个D推来的,2个H和2个D总共有H D H D,H H D D两种排列,3个H和一个D总共有H D H H,H H D H,H H H D三种排列,然后在H D H D,H H D D的后面添加一个H就是2中排列,在H D H H,H H D H,H H H D的后面添加一个D就有3种方案,所以总共就是5种方案(其它的添加方法都是重复的,不信的话自己可以试一下)
代码如下:
/*
* d.cpp
*
* Created on: 2015年2月4日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 21;
long long a[maxn][maxn];
void prepare() {
int i;
for (i = 0; i < maxn; ++i) {
a[i][0] = 1;//当D的个数为0时,无论多少个H,它的排列数都只有一种.
}
//需要注意的是,这里a[0][i] = 0 .没初始化,因为默认值就是0.因为没有H,这种方案就不成立了
int j;
for (i = 1; i < maxn; ++i) {
for (j = i; j < maxn; ++j) {
a[j][i] = a[j - 1][i] + a[j][i - 1];
}
}
}
int main() {
prepare();
int n, m;
while (scanf("%d%d", &n, &m) != EOF) {
printf("%lld\n", a[n][m]);
}
return 0;
}