zoukankan      html  css  js  c++  java
  • 禁止字符串(挑战程序设计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);
    }
  • 相关阅读:
    Maven 集成Tomcat插件
    dubbo 序列化 问题 属性值 丢失 ArrayList 解决
    docker 中安装 FastDFS 总结
    docker 从容器中拷文件到宿主机器中
    db2 相关命令
    Webphere WAS 启动
    CKEDITOR 4.6.X 版本 插件 弹出对话框 Dialog中 表格 Table 自定义样式Style 问题
    SpringMVC JSONP JSON支持
    CKEDITOR 3.4.2中 按钮事件中 动态改变图标和title 获取按钮
    git回退到远程某个版本
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11671879.html
Copyright © 2011-2022 走看看