Atcoder beginner contest 122D We like AGC

https://atcoder.jp/contests/abc122/tasks/abc122_d
题意:由AGCT组成的长度为n的字符串中满足1.不含有“AGC”,2.把任意两个相邻的字符交换后也满足没有“AGC”。求这样的字符串个数。
思路:可以用dp解决。当前能不能这个字母只于前3个字母有关。设dp[i][a][b][c]为长度为i时第i-3个字母是c,第i-2个字母是b,第i-1个字母是a时的数量。则可以枚举i,a,b,c和当前的字母d,abcd只有5种情况不成立,剩下的都可以加起来。5种情况分别是:?AGC,?ACG,?GAC,A?GC,AG?C。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pii pair
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
using namespace std;
const ll mod=1e9+7;
ll dp[110][4][4][4];
bool check(int x,int y,int z,int w)//agct
{
	if((y==0&&z==1&&w==2)||(y==0&&z==2&&w==1)||(y==1&&z==0&&w==2)||(x==0&&z==1&&w==2)||(x==0&&y==1&&w==2))
	{
		return 0;
	}
	return 1;
}
int main()
{
	int i,j,k,n,m,x,y,z;
	scanf("%d",&n);
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			for(k=0;k<4;k++)
				if((i==0&&j==1&&k==2)||(i==0&&j==2&&k==1)||(i==1&&j==0&&k==2))
					dp[3][i][j][k]=0;
				else
					dp[3][i][j][k]=1;
	for(i=4;i<=n;i++)
		for(x=0;x<4;x++)
			for(y=0;y<4;y++)
				for(z=0;z<4;z++)
					for(j=0;j<4;j++)
						if(check(x,y,z,j))
						{
							dp[i][y][z][j]+=dp[i-1][x][y][z];
							dp[i][y][z][j]%=mod;
						}
	ll sum=0;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			for(k=0;k<4;k++)
			{
				sum+=dp[n][i][j][k];
				sum%=mod;
			}
	printf("%lld",sum);
	return 0;
}

你可能感兴趣的:(atcoder)