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);
    }
  • 相关阅读:
    Yii常用路径说明
    PHP-redis中文文档
    PHP 判断客户端是IOS还是Android
    yiii 框架登录 判断是否是游客模式及未登录状态
    php实现数字格式化,数字每三位加逗号的功能函数
    php array_udiff_uassoc比较数组的键值与值
    php--数组函数array
    安装Postman
    vue指令
    vue 错误记录
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11671879.html
Copyright © 2011-2022 走看看