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

ZOJ3791_An Easy Game

时间:2014-08-03 20:26:35      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   for   ar   div   

给出两个等长的字符串,每次需要改变m个数字,每次必须改变k个数字,求从第一个串变化到第二个串的方案数。

DP。f[i][j]改变i步后,有j个位置被改变的方案数。然后直接枚举当前改变的几个位置是前面重合的。

然后统计答案输出即可。

 

 

#include <iostream>
#include <cstring>
#include <cstdio>
#define M 1000000009
#define maxn 105
typedef long long ll;
using namespace std;

ll C[maxn][maxn];
ll f[maxn][maxn];
int n,k,m,change;
ll ans;

ll power(ll A,ll B)
{
    ll tot=1;
    while (B){
        if (B&1) tot=tot*A%M;
        A=A*A%M,B>>=1;
    }
    return tot;
}

void _init()
{
    memset(C,0,sizeof C);
    C[0][0]=1;
    for (int i=1; i<maxn; i++){
        C[i][0]=1;
        for (int j=1; j<=i; j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%M;
    }
}

int main()
{
    _init();
    char s1[maxn],s2[maxn];
    while (scanf("%d%d%d",&n,&k,&m)!=EOF){
        change=0;
        scanf("%s%s",s1,s2);
        for (int i=0; i<n; i++)
            if (s1[i]!=s2[i]) change++;
        memset(f,0,sizeof f);
        f[0][0]=1;
        for (int i=0; i<k; i++)//after the ith time of changes
            for (int j=0; j<=n; j++){//the number of 1 is j
                if (f[i][j]==0) continue;
                for (int x=max(0,j+m-n); x<=min(j,m); x++){
                    f[i+1][j-x+m-x]+=f[i][j]*(C[j][x]*C[n-j][m-x]%M)%M;
                    f[i+1][j-x+m-x]%=M;
                }
            }
        ans=f[k][change]*power(C[n][change],M-2)%M;
        printf("%d\n",(int)ans);
    }
    return 0;
}

 

ZOJ3791_An Easy Game,布布扣,bubuko.com

ZOJ3791_An Easy Game

标签:style   blog   color   os   io   for   ar   div   

原文地址:http://www.cnblogs.com/Canon-CSU/p/3888707.html

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