题解:AT_abc122_d [ABC122D] We Like AGC
你说得对,但是我不喜欢 AGC。
思路
先考虑什么样的字符串是不能出现的。
不难发现,违反限制 的有:
AGC。
违反限制 的有:
ACG(交换C和G);GAC(交换G和A);AG?C(交换?和C,其中?是A、C、G、T中任一个);A?GC(交换A和?)。
然后就可以 dp 了。
我们用 代表 A, 代表 G, 代表 C, 代表 T。
设 表示现在前 位的串已经覆盖好,最后三位分别是 和 和 的方案数。
那么我们枚举第 位 。如果构成了上面的五种串,则不可行,反之就让 加上 ,即这个状态可以从上一个状态转移来。
于是做完了。
代码
#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;
}

浙公网安备 33010602011771号