• zoj3791(An Easy Game) DP


    意甲冠军:给定两个01弦s1,s2.每一个变化s1在m字 - 位。要求k制作步骤之后s1变s2有多少种方法。


    解法:DP,关键是状态的设计。考虑还是唯一性和可传递性。dp[i][j]表示第i步后有j个不同到目标的走法数。记忆化搜索dp[0][dif](dif表示初始时不同字符的个数)。

    转移时候枚举选择情况就可以。


    代码:

    /******************************************************
    * author:xiefubao
    *******************************************************/
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <string.h>
    //freopen ("in.txt" , "r" , stdin);
    using namespace std;
    
    #define eps 1e-8
    const double pi=acos(-1.0);
    typedef long long LL;
    const int Max=110;
    const int INF=1000000009;
    
    int n,k,m;
    string s1,s2;
    LL C[Max][Max];
    int init()
    {
        for(int i=0; i<Max; i++)
            for(int j=0; j<=i; j++)
                C[i][j]=j?

    (C[i-1][j-1]+C[i-1][j])%INF:1; } LL dp[Max][Max]; int dif; LL dfs(int step,int num) { if(dp[step][num]!=-1) return dp[step][num]; LL ans=0; for(int i=0; i<=num; i++) { if(i+n-num<m) continue; if(i>m) break; ans=(ans+(C[num][i]*C[n-num][m-i])%INF*dfs(step+1,num-i+m-i))%INF; } return dp[step][num]=ans; } int main() { init(); while(scanf("%d%d%d",&n,&k,&m)==3) { dif=0; memset(dp,-1,sizeof dp); cin>>s1>>s2; for(int i=0; i<n; i++) if(s1[i]!=s2[i]) dif++; dp[k][0]=1; for(int i=1;i<=n;i++) dp[k][i]=0; cout<<dfs(0,dif)<<' '; } return 0; }


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    MySQL源代码解读(二)
    MySQL源代码解读(一)
    C语言中如何对串口进行操作
    mysql 运行概图
    Yacc 与 Lex
    外键建索引
    提高SQL查询效率
    MySQL源代码分析:(1)Main函数
    Linux "could not open default font 'fixed'."
    转帖 浅析ARM汇编语言子例程设计方法
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4802792.html
Copyright © 2020-2023  润新知