• ZOJ3791_An Easy Game


    给出两个等长的字符串,每次需要改变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
    ",(int)ans);
        }
        return 0;
    }
  • 相关阅读:
    js 数组相减
    js 对象数组去重
    vue 首次不触发watch的解决方法
    "神药"推荐--紫花地丁
    openstack 平台添加 nvidia vGPU
    string易错点整理总结
    CentOS安装图形界面
    CentOs安装ssh和scp
    数组把0移到末尾
    Windows下Celery安装与下使用
  • 原文地址:https://www.cnblogs.com/lochan/p/3888707.html
Copyright © 2020-2023  润新知