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;
}