CCF 201312-4 有趣的数 (DP)

版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82353983

原题地址: http://118.190.20.162/view.page?gpid=T2

思路:考虑dp,状态转移及定义详见代码

#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
/*
一. 2
二. 2 0
三. 2 3
四. 2 0 1
五. 2 3 0
六. 2 3 0 1
定义6种dp状态
*/
ll dp[1005][10];//dp[i][j]表示长度为i,状态为j的种类数

int main() {
    int n;
    scanf("%d", &n);
    dp[1][1] = 1;
    for (int  i = 2; i <= n; i++) {
        dp[i][1] = 1;
        dp[i][2] = dp[i - 1][1] + 2 * dp[i - 1][2];
        dp[i][3] = dp[i - 1][1] + dp[i - 1][3];
        dp[i][4] = dp[i - 1][2] + 2 * dp[i - 1][4];
        dp[i][5] = dp[i - 1][2] + dp[i - 1][3] + 2 * dp[i - 1][5];
        dp[i][6] = dp[i - 1][4] + dp[i - 1][5] + 2 * dp[i - 1][6];
        /*
        以下的状态转移均由长度为i-1得来
        1.以状态1结尾的只有一种,那就全部是2
        2.以状态2结尾的可以由状态1末尾加一个0得来,或者状态2末尾加一个0或1(这是乘以2倍的原因)
        3.以状态3结尾的可以由状态1末尾加一个3得来,或者由状态3末尾加一个3得来
        4.以状态4结尾的可以由状态2末尾加一个1得来,或者状态4末尾加一个0或3得来(2倍)
        5.以状态5结尾的可以由状态2末尾加一个3得来,由状态3末尾加一个0得来,或者状态5结尾加一个0或3
        6.以状态6结尾的可以由状态4末尾加一个3得来,由状态5末尾加一个1得来,或者状态5结尾加一个0或3
        */
        for (int k = 1; k <= 6; k++) dp[i][k] %= mod;
    }
    printf("%lld\n", dp[n][6]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/82353983