ZOJ-3791 An Easy Game DP
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ-3791 An Easy Game DP相关的知识,希望对你有一定的参考价值。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3791
给出两个长度为n的01串,要求进行k次变化,将串1变为串2,每次变化要改变m个字符。
dp[i][j]的含义是在i次变化后,还有j个字符变的情况数,最终结果是dp[k][0]。
每次变化时,在需要改变的字符中选取l个,在不需要改变的字符中就要选(m - l)个,即变化后需要改变的字符数变为(j + 2 * l - m)
转移方程为 dp[i + 1][j + 2 * l - m] = (dp[i + 1][j + 2 * l - m] + C[j][m - l] * C[n - j][l] * dp[i][j])
最开始求组合数忘记取模,找bug找的头皮发麻……
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<string.h> int main() { char str1[101], str2[101]; long long int n, k, m, i, dp[101][101], j, l, dif = 0, w; long long int C[101][101]; long long int mod = 1e9 + 9; C[0][0] = 1; for(i = 0; i <= 100; i++){ C[i][0] = 1; C[i][i] = 1; } for(i = 1; i <= 100; i++){ for(j = 1; j < i; j++){ C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod; } } while (scanf("%lld %lld %lld", &n, &k, &m) != EOF){ dif = 0; memset(dp, 0, sizeof(dp)); scanf("%s", str1); scanf("%s", str2); for(i = 0; i < n; i++) if (str2[i] != str1[i]) dif++; dp[0][dif] = 1; for (i = 0; i < k; i++) { for (j = 0; j <= n; j++) { for (l = 0; l <= m; l++) { if((j + 2 * l - m) < 0) continue; if((j + 2 * l - m) > n) break; dp[i + 1][j + 2 * l - m] = (dp[i + 1][j + 2 * l - m] % mod + C[j][m - l] * C[n - j][l] % mod * dp[i][j] % mod) % mod; } } } printf("%lld\n", dp[k][0]); } return 0; }
以上是关于ZOJ-3791 An Easy Game DP的主要内容,如果未能解决你的问题,请参考以下文章
Light OJ 1031 - Easy Game(区间dp)
杭电OJ(HDU)-ACMSteps-Chapter Two-《An Easy Task》《Buildings》《decimal system》《Vowel Counting》
2016"百度之星" - 初赛(Astar Round2A) 1004 D Game 区间DP