题目链接: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 }