• ZROI2018提高day6t2


    传送门

    分析

    将所有字母分别转化为1~26,之后将字符串的空位补全为0,?设为-1,我们设dp[p][c][le][ri]表示考虑le到ri个字符串且从第p位开始考虑,这一位最小填c的方案数,具体转移见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const long long mod = 990804011;
    #define add(x,y) x=(x+y)%mod
    long long dp[25][30][60][60];
    int len[60],n,m,a[60][25];
    char s[60][25];
    inline long long getdp(int p,int c,int le,int ri){
        if(c>26)return 0;
        if(p>m)return le==ri;
        if(dp[p][c][le][ri]!=-1)return dp[p][c][le][ri];
        dp[p][c][le][ri]=getdp(p,c+1,le,ri);
        for(int i=le;i<=ri;i++){
          if(!c&&a[i][p]==-1)break;
          if(a[i][p]>=0&&a[i][p]!=c)break;
          long long t=getdp(p+1,0,le,i);
          if(i!=ri)t=t*getdp(p,c+1,i+1,ri)%mod;
          add(dp[p][c][le][ri],t);
        }
        return dp[p][c][le][ri];
    }
    int main(){
        int i,j,k;
        scanf("%d",&n);
        memset(dp,-1,sizeof(dp));
        for(i=1;i<=n;i++){
          scanf("%s",s[i]);
          len[i]=strlen(s[i]);
          m=max(m,len[i]);
        }
        for(i=1;i<=n;i++)
          for(j=1;j<=m;j++)
            if(j>len[i])a[i][j]=0;
              else if(s[i][j-1]=='?')a[i][j]=-1;
              else a[i][j]=s[i][j-1]-'a'+1;
        printf("%lld
    ",getdp(1,0,1,n));
        return 0;
    }
  • 相关阅读:
    计算机科学中最重要的32个算法
    趣事
    深度学习迷你地图
    物理学
    代数几何
    Node.js 文件系统
    Node.js 常用工具util包
    Node.js 全局对象
    favi.icon是什么?
    Node.js 路由
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9798415.html
Copyright © 2020-2023  润新知