zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 122 D

    D - We Like AGC


    Time Limit: 2 sec / Memory Limit: 1024 MB

    Score : 400400 points

    Problem Statement

    You are given an integer NN. Find the number of strings of length NN that satisfy the following conditions, modulo 109+7109+7:

    • The string does not contain characters other than ACG and T.
    • The string does not contain AGC as a substring.
    • The condition above cannot be violated by swapping two adjacent characters once.

    Notes

    A substring of a string TT is a string obtained by removing zero or more characters from the beginning and the end of TT.

    For example, the substrings of ATCODER include TCOATCODERATCODER and  (the empty string), but not AC.

    Constraints

    • 3N1003≤N≤100

    Input

    Input is given from Standard Input in the following format:

    NN
    

    Output

    Print the number of strings of length NN that satisfy the following conditions, modulo 109+7109+7.


    Sample Input 1 Copy

    Copy
    3
    

    Sample Output 1 Copy

    Copy
    61
    

    There are 43=6443=64 strings of length 33 that do not contain characters other than ACG and T. Among them, only AGCACG and GAC violate the condition, so the answer is 643=6164−3=61.


    Sample Input 2 Copy

    Copy
    4
    

    Sample Output 2 Copy

    Copy
    230
    

    Sample Input 3 Copy

    Copy
    100
    

    Sample Output 3 Copy

    Copy
    388130742
    

    Be sure to print the number of strings modulo 109+7109+7.

    题意:

    给你一个数字N,N的范围是3~100

    让你求出有多少种可能的字符串,使之只包括这四种字符 ACG and T.

    并且字符串不含有“AGC”这个子串,并且仅交换一次相邻的字符也不含有“AGC”这个子串。

    思路:

    我们根据第一个样例就可以看出N=3的所有情况。

    因为我们考虑的是DP的写法,先思考如何定义状态,

    我们通过思考可以知道我们从N=3转到N=4的状态的时候,我们要考虑整个字符串的后3个字符才可以确定最后一位能不能加上我们在转移的字符,

    那么我们不妨在定义状态的时候就把整个字符串的后3位字符都存下来。

    所以我们定义状态如下:

    DP[ len ][i] [ j ] [ k ] = 长度为len的字符串中,后三位字符串依次是ijk的字符串有多少种。

    这里因为只有四种字母,我们不妨给四个字符进行用数码编号表示,以此来简化我们的程序编写;

    我们按照字典序把{'A','C','G','T'}; 编为 0 1 2 3.

    那么我们现在从N=4开始考虑,

    我们知道以下几种情况是不能满足条件的

    后三位是  我们不能接上

    *AG  C

    *AC  G

    *GA  C

    A*G  C

    AG*  C

    我们只需要在转移的时候,把这5种会产生不符合条件的字符串给删除掉(即不计入计数)

    就可以顺利的推出答案了。

     

    具体转移的细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    const ll mod = 1e9+7ll;
    ll dp[110][5][5][5];
    char c[6]={'A','C','G','T'};
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        // gbtb*/
        cin>>n;
        string temp="123";
        int num=0;
        // repd(i,0,3)
        // {
        //     temp[0]=c[i];
        //     repd(j,0,3)
        //     {
        //         temp[1]=c[j];
        //         repd(k,0,3)
        //         {
        //             temp[2]=c[k];
        //             cout<<num++<<" ";
        //             cout<<temp<<endl;
        //         }
        //     }
        // }
        // char c[6]={'A','C','G','T'};
        repd(i,0,3)
        {
            repd(j,0,3)
            {
                repd(k,0,3)
                {
                    dp[3][i][j][k]=1;
                }
            }
        }
        dp[3][0][1][2]=0;
        dp[3][0][2][1]=0;
        dp[3][2][0][1]=0;
        ll cnt=0ll;
        repd(len,4,n)
        {
            repd(i,0,3)
            {
                repd(j,0,3)
                {
                    repd(k,0,3)
                    {
                        cnt=0ll;
    
                        repd(ii,0,3)
                        {
                            repd(jj,0,3)
                            {
                                repd(kk,0,3)
                                {
                                    //{'A','C','G','T'};
                                    if(jj==i&&kk==j)
                                    {
                                        if(k==1&&kk==2&&jj==0)
                                        {
    
                                        }else if(k==1&&kk==0&&jj==2)
                                        {
    
                                        }else if(k==2&&kk==1&&jj==0)
                                        {
    
                                        }else if(k==1&&kk==2&&ii==0)
                                        {
    
                                        }else if(k==1&&jj==2&&ii==0)
                                        {
    
                                        }else
                                        {
                                            cnt+=dp[len-1][ii][jj][kk];
                                            cnt=(cnt+mod)%mod;
                                        }
                                    }
    
    
                                }
                            }
                        }
                        cnt=(cnt+mod)%mod;
                        dp[len][i][j][k]=cnt;
    //                    printf("%d %d %d %lld
    ",i,j,k,cnt);
                    }
                }
            }
        }
        ll ans=0ll;
        repd(i,0,3)
        {
            repd(j,0,3)
            {
                repd(k,0,3)
                {
                    ans+=dp[n][i][j][k];
                    ans=(ans+mod)%mod;
                }
    
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }

    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    web.xml模板
    log4j.properties模板
    springmvc-config.xml模板
    applicationContext.xml配置druid连接池
    mybatis-config.xml模板
    mapper.xml模板
    Servlet基础认识
    单例模式的懒汉饿汉
    霜降小悟
    忙闲有致
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10692577.html
Copyright © 2011-2022 走看看