[HackerCup Round1 3] Winning at Sports (动态规划)

题目链接:https://www.facebook.com/hackercup/problems.php?pid=688426044611322&round=344496159068801

题目大意:两种赢法,一种叫做stress-free,另外一种叫做stressful。问你给定最终成绩,stress-free和stressful的局数各有多少。

 

建立状态:dp[i][j]代表比分为i-j的时候,stress-free的局数,有状态转移:dp[i][j] = dp[i-1][j]+dp[i][j-1]

因为如果说比分为i-1:j的话,那么我们添加一盘比赛,给i-1添加一分的话,仍然符合stress-free。

同样i:j-1也是一样:因为i严格大于j,因此我们给j-1增加一分的话,对方的总盘数为j,因为i:j-1的时候,中间的过程始终满足i‘>j-1‘,因此添加一分也不影响满足题意。

最终结果存在dp[a][b]中。

 

建立状态:f[i][j]代表比分为i-j的时候,i≥j的盘数。之所以这么做是因为其与题意要求等价。

状态转移方程不变,只是转移的边界变成了i≥j。

最终答案是f[b][b]

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int MOD = 1000*1000*1000+7;
 7 const int MAX_N = 2222;
 8 int dp[MAX_N][MAX_N];
 9 int f[MAX_N][MAX_N];
10 int T;
11 int a,b;
12 
13 int main(){
14 //    freopen("input.txt","r",stdin);
15 //    freopen("output.txt","w",stdout);
16     memset(dp,0,sizeof(dp));
17     memset(f,0,sizeof(f));
18     for(int i=1;i<=2000;i++){
19         dp[i][0] = 1;
20     }
21     for(int i=2;i<=2000;i++){
22         for(int j=1;j<i;j++){
23             dp[i][j] = (dp[i][j-1]+dp[i-1][j])%MOD;
24         }
25     }
26     for(int i=0;i<=2000;i++){
27         f[i][0] = 1;
28     }
29     for(int i=1;i<=2000;i++){
30         for(int j=1;j<=i;j++){
31             f[i][j] = (f[i][j-1]+f[i-1][j])%MOD;
32         }
33     }
34     scanf("%d",&T);
35     for(int cases = 1; cases <= T; cases++){
36         scanf("%d-%d",&a,&b);
37         printf("Case #%d: %d %d\n",cases,dp[a][b],f[b][b]);
38     }
39     return 0;
40 }

 

[HackerCup Round1 3] Winning at Sports (动态规划)

上一篇:Win7 系统下安装CentOS7 双系统


下一篇:30条MySQL查询的优化方法