题解:AT_abc122_d [ABC122D] We Like AGC

你说得对,但是我不喜欢 AGC。

思路

先考虑什么样的字符串是不能出现的。

不难发现,违反限制 22 的有:

  • AGC

违反限制 33 的有:

  • ACG(交换 CG);
  • GAC(交换 GA);
  • AG?C(交换 ?C,其中 ?ACGT 中任一个);
  • A?GC(交换 A?)。

然后就可以 dp 了。

我们用 00 代表 A11 代表 G22 代表 C33 代表 T

dpi,j,k,ldp_{i,j,k,l} 表示现在前 i1i-1 位的串已经覆盖好,最后三位分别是 jjkkll 的方案数。

那么我们枚举第 iipp。如果构成了上面的五种串,则不可行,反之就让 dpi,k,l,pdp_{i,k,l,p} 加上 dpi1,j,k,ldp_{i-1,j,k,l},即这个状态可以从上一个状态转移来。

于是做完了。

代码

#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
int n,dp[105][4][4][4];
int ans;
int main(){
	scanf("%d",&n);
	if(n==1){
		printf("4");
		return 0;
	}
	if(n==2){
		printf("16");
		return 0;
	}
	if(n==3){
		printf("61");
		return 0;
	}
	//A0 G1 C2 T3
	dp[0][3][3][3]=1;
	for(int i=1;i<=n;i++){
		for(int j=0;j<4;j++){
			for(int k=0;k<4;k++){
				for(int l=0;l<4;l++){
					for(int p=0;p<4;p++){
						if(k==0&&l==1&&p==2)continue;//AGC
						if(k==0&&l==2&&p==1)continue;//ACG
						if(k==1&&l==0&&p==2)continue;//GAC
						if(j==0&&k==1&&p==2)continue;//AG-C
						if(j==0&&l==1&&p==2)continue;//A-GC 
						dp[i][k][l][p]=(dp[i-1][j][k][l]+dp[i][k][l][p])%mod;
					}
				}
			}
		}
	}
	for(int i=0;i<4;i++){
		for(int j=0;j<=3;j++){
			for(int k=0;k<=3;k++){
				ans=(ans+dp[n][i][j][k])%mod;
			}
		}
	}
	printf("%d\n",ans);
	return 0;
}
posted @   Weslie_qwq  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示