AtCoder-Contest-122-D-We-Like-AGC

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 and T.
  • 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;
}

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/89032847
今日推荐