• 禁止字符串(挑战程序设计368页)


    题意:考虑只由'A','G','C','T'四种字符组成的DNA字符串。给定一个长度为k的字符串S。计算长度恰好为n且不包含S的字符串的个数。输出答案mod 10009的结果

    题解:

    对于每一个串s,都可能由一些状态转移到另外一些状态。例如: S=“ATCATCG”,假设我当前s=AATC,而这个状态所对应的状态为*ATC,假如我在这个AATC后加上A,那么s就会转移到*A这个状态。

    为什么呢,因为我如果要组成S的话,那么前缀必定相等,所以就会有这样的转移关系!所以就可以用动态规划求解

    技巧:先预处理出添加某个字符后转移到的状态表,之后根据一些简单的判断就可以进行DP了

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back
    const int mod=10009;
    void read(int &a)
    {
        a=0;int d=1;char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    int n,k;
    string S;
    int next[10009][5];///添加某个字符后转移到的状态
    int dp[10009][105];
    char AGCT[5]={'A','G','C','T'};
    void solve()
    {
        for(re int i=0;i<k;i++)
        {
            for(re int j=0;j<4;j++)
            {
                string s=S.substr(0,i)+AGCT[j];///截取S的前i个字符,然后加题目给定的4个字符之一
                while(S.substr(0,s.length())!=s)///当S的前缀不是s时做循环
                    s=s.substr(1);///取s以1之后的所有字符,相当于删除第一个字符后剩下的所有字符
                next[i][j]=s.length();///添加j字符后转移到的状态的字符前缀长度
            }
        }
    }
    int main()
    {
        read(n),read(k);cin>>S;
        solve();
        dp[0][0]=1;
        for(re int i=1;i<k;i++) dp[0][i]=0;
        for(re int t=0;t<n;t++)
        {
            for(re int i=0;i<k;i++) dp[t+1][i]=0;
            for(re int i=0;i<k;i++)
            {
                for(re int j=0;j<4;j++)
                {
                    int ti=next[i][j];
                    if(ti==k) continue;///如果当前字符前缀长度已经为k,那么明显是不符合要求的
                    //cout<<ti<<" "<<i<<endl;
                    dp[t+1][ti]=(dp[t+1][ti]+dp[t][i])%mod;///t+1长度的,只要当前next[i][j]匹配长度不为k,那么ti可以由i转移过来,所以就有这个转移式!!!
                }
            }
        }
        int ans=0;
        for(re int i=0;i<k;i++) ans=(ans+dp[n][i])%mod;///将长度为n的,与S匹配最长为i的串全部累加就是答案
        printf("%d
    ",ans);
    }
  • 相关阅读:
    Diablo3 英雄榜-显示用户的装备信息-Volley读取API的图片资源,使用MySingleton管理RequestQueue
    Diablo3英雄榜-使用Volley和Gson来处理暴雪API的Json数据
    Diablo3英雄榜-API分析
    《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent
    《Android编程权威指南》-读书笔记(十)-从一个内涵段子开始第二个例子
    さらば、博客园よ
    Kotlin有点用力过猛了
    记一个耻辱
    备份一个省市区JSON数据
    博(wǒ)客(zì)园(jǐ)的排版真是丑毙了
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11671879.html
Copyright © 2020-2023  润新知