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

ZOJ-3791 An Easy Game DP

时间:2017-07-10 12:07:42      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:can   memset   while   字符   stdio.h   eof   变化   bug   组合数   

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

标签:can   memset   while   字符   stdio.h   eof   变化   bug   组合数   

原文地址:http://www.cnblogs.com/pulisicgo/p/7144867.html

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