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的主要内容,如果未能解决你的问题,请参考以下文章

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

board game作业代写代写board game程序C程序代写

board game作业代写代写board game程序C程序代写