码迷,mamicode.com
首页 > 其他好文 > 详细

“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 (部分题解)

时间:2015-03-30 21:08:45      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛

 

 

 

 

F

自动售货机

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 60            测试通过 : 13 

题目描述

 

 

教学楼有一台奇怪的自动售货机,它只售卖一种饮料,单价5元,并且只收5元、10元面值的货币,但是同学们都很喜欢喝。这个售货机里没有多余的找零,也就是说如果一个持有10元的同学第一个购买,则他不能获得5元找零,但是如果在他之前有一个持有5元的同学买了这种饮料,则他可以获得5元找零。

 

假设售货机的货源无限,每人只买一罐,现在有N个持有5元的同学和M个持有10元的同学想要购买,问一共有多少种排队方法可以让每个持有10元的同学都获得找零。(这里的排队方法以某一位置上人持的钱数来分,即只要同一位置上的同学所持钱的数目相同,就算同一种排队方法)


输入

 

多组测试数据

 

每组包含两个整数N,M(1<=M<=N<=1000),分别表示持有5元和10元的同学个数。

 

输出

 

输出一个整数,表示排队方法总数。由于结果可能很大,所以结果需要模1000000007。

 

样例输入

1 1
2 1
3 1

样例输出

1
2
3

 

题目来源

hjp

 

题解转自田神:

http://blog.csdn.net/tc_to_top/article/details/44745987

 

 

题目分析:这题其实很简单,开始想的太复杂了,开始当作卡特兰数 (Catalan数)做其实就是(C(n+m, m)%mod - C(n+m, m-1)%mod)%mod,数组递推组合数T了 ,用java写大数结果noj上mle,连乘组合数取余写跪了,下面说这题应该怎么做。

其实就是一个dp,dp[i][j]表示有i个人有5元,j个人有10元的排队方案数,我们可以发现:

dp[i][0] = 1,因为大家都只有5元,怎么排都是一种方案

i < j时dp[i][j] = 0,因为有5元的人比有10元的少,必然会出现找不开的情况,那么此时方案数就是0

不是以上两种情况时:dp[i][j]的方案数由dp[i - 1][j] + dp[i][j - 1]递推得到,考虑第m+n个人的状态

1.第m+n个人100,m+n-1里有m个50,n-1个100则dp[m][n-1]
2.第m+n个人50,m+n-1里有m-1个50,n个100则dp[m-1][n]

 

 

最后竟然忘了先预处理算一遍,- -

 

Accepted
937MS
  16020K
887Byte
2015-03-30 20:03:08.0

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <stack>
 4 #include <vector>
 5 #include <queue>
 6 #include <algorithm>
 7 
 8 #define ll long long
 9 int const N = 1005;
10 int const M = 205;
11 int const inf = 1000000000;
12 ll const mod = 1000000007;
13 
14 using namespace std;
15 
16 ll dp[2*N][N];
17 int n,m;
18 
19 void ini1()
20 {
21     memset(dp,0,sizeof(dp));
22     dp[1][0]=1;
23     int i,j;
24     for(i=2;i<=2000;i++){
25         for(j=0;j<=i/2;j++){
26             dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%mod;
27         }
28     }
29 }
30 
31 void ini()
32 {
33 
34 }
35 
36 void solve()
37 {
38 
39 }
40 
41 void out()
42 {
43     printf("%I64d\n",dp[n+m][m]);
44 }
45 
46 int main()
47 {
48     ini1();
49     //freopen("data.in","r",stdin);
50    // freopen("data.out","w",stdout);
51     //scanf("%d",&T);
52     //for(int cnt=1;cnt<=T;cnt++)
53    // while(T--)
54     while(scanf("%d%d",&n,&m)!=EOF)
55     {
56         ini();
57         solve();
58         out();
59     }
60 }

 

“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 (部分题解)

标签:

原文地址:http://www.cnblogs.com/njczy2010/p/4379034.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!