AtCoder Beginner Contest 122 English D We Like AGC

在这里插入图片描述
题意:给你一个数n,问你长度为n的字符串中有多少个不包含AGC的字符串,字符串只包含字母: ‘A’,‘C’,‘G’,‘T’,字符串可以进行一次交换,例如:AGC字符串通过交换一次可以得到ACG,
GAC;
思路:自己不会做,只能百度别人的题解,这里打上自己的理解,先找一下规律,就比如组成一个长度为4的字符串,可以发现它仅与前三个字符有关,那么组成长度为5的字符串呢,可以发现还是仅与前三个字符串有关。很明显这就是一个dp题,组成一个字符串,有八种不符合情况
在这里插入图片描述
a代表当前字符的前面第三位
b代表当前字符的前面第二位
c代表当前字符的前面第一位
d代表当前字符
知道这八种情况就可以直接dp了
代码如下:

#include<bits/stdc++.h>
#define LL long long
#define Max 100005
#define Mod 1e9+7
const LL mod=1e9+7;
const LL inf=0x3f3f3f3f;
using namespace std;
map<int,string> m;
int dp[105][5][5][5];
bool check(int a,int b,int c,int d)
{

    if(m[a]+m[c]+m[b]=="AGC")
        return false;
    if(m[a]+m[b]+m[c]=="AGC")
        return false;
    if(m[a]+m[c]+m[d]=="AGC")
        return false;
    if(m[a]+m[b]+m[d]=="AGC")
        return false;
    if(m[b]+m[c]+m[d]=="AGC")
        return false;
    if(m[b]+m[d]+m[c]=="AGC")
        return false;
    if(m[b]+m[a]+m[c]=="AGC")
        return false;
    if(m[c]+m[b]+m[d]=="AGC")
        return false;
    return true;
}
int main()
{
    int n;
    scanf("%d",&n);
   dp[0][0][0][0]=1;
    m[0]='W',m[1]='A',m[2]='C',m[3]='G',m[4]='T';
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=4; j++)
        {
            for(int k=0; k<=4; k++)
            {
                for(int l=0; l<=4; l++)
                {
                    for(int m=0; m<=4; m++)
                    {
                        if(check(m,l,k,j))
                            dp[i][j][k][l]=(dp[i][j][k][l]+dp[i-1][k][l][m])%mod;
                    }
                }
            }
        }
    }
    int ans=0;
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            for(int k=1;k<=4;k++){
                ans=(ans+dp[n][i][j][k])%mod;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Gee_Zer/article/details/88806210
今日推荐