Problem Statement
You are given an integer N. Find the number of strings of length N that satisfy the following conditions, modulo 109+7:
- The string does not contain characters other than
A
,C
,G
andT
. - The string does not contain
AGC
as a substring. - The condition above cannot be violated by swapping two adjacent characters once.
Notes
A substring of a string T is a string obtained by removing zero or more characters from the beginning and the end of T.
For example, the substrings of ATCODER
include TCO
, AT
, CODER
, ATCODER
and `` (the empty string), but not AC
.
Constraints
- 3≤N≤100
Input
Input is given from Standard Input in the following format:
N
Output
Print the number of strings of length N that satisfy the following conditions, modulo 109+7.
Sample Input 1
3
Sample Output 1
61
There are 43=64 strings of length 3 that do not contain characters other than A
, C
, G
and T
. Among them, only AGC
, ACG
and GAC
violate the condition, so the answer is 64−3=61.
Sample Input 2
Copy
4
Sample Output 2
230
Sample Input 3
100
Sample Output 3
388130742
Be sure to print the number of strings modulo 109+7.
题目大意就是字符串只能由A、C、G、T组成,然后子串中不能出现AGC,还有任意两个相邻的字符交换后不能出现AGC。也就是说排除一下几种情况:
AGC
ACG
GAC
AXGC //X代表A C G T
AGXC
所以我只需要定义dp[i][j][p][q]
代表前i个字符,最后3个字符为j,p,q的方案数(0代表A,1代表C,2代表G,3代表T)。详细见代码
代码:
#include <stdio.h>
#define ll long long
#define mod 1000000007
ll dp[105][4][4][4] = {0};
bool pan(int a, int b, int c) {
if (a == 0 && b == 2 && c == 1) return false;
if (a == 0 && b == 1 && c == 2) return false;
if (a == 2 && b == 0 && c == 1) return false;
return true;
}
bool pan1(int a, int b, int c) {
if (a == 0 && b == 2 && c == 1) return false;
return true;
}
int main () {
int n;
scanf("%d", &n);
if (n == 1) {
printf("4\n");
} else if(n == 2) {
printf("16\n");
} else {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int p = 0; p < 4; p++) {
if (pan(i, j, p)) {
dp[3][i][j][p] = 1;
}
}
}
}
for (int k = 4; k <= n; k++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int p = 0; p < 4; p++) {
//dp[k][i][j][p]
if (pan(i, j, p)) {
for (int q = 0; q < 4; q++) {
if (pan(q, i, j) && pan1(q, j, p) && pan1(q, i, p)) {
dp[k][i][j][p] = (dp[k][i][j][p] + dp[k - 1][q][i][j]) % mod;
}
}
}
}
}
}
}
ll ans = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int p = 0; p < 4; p++) {
ans = (ans + dp[n][i][j][p]) % mod;
}
}
}
printf("%lld\n", ans);
}
return 0;
}
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢