hdu5642 数位dp

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5642

题意:一个长度为n的序列,合法序列为字符中不能出现长度大于3的连续相等的字符,求一共有多少个合法序列。

好久之前写过两道数位dp,早就不记得是什么了。。总之数位dp中,总有一维数组是要代表位数的。

代码如下,思路见注释。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int MOD=1e9+7;

int dp[2005][30];
//dp[i][j] 表示长度为i结尾字符为j的合法字符有多少种

void init()
{
    memset(dp,0,sizeof(dp));
    for(int i=0; i<26; i++) //前三位都是合法字符,初始化数值
    {
        dp[1][i]=1;
        dp[2][i]=26;
        dp[3][i]=676;
    }
    for(int i=4; i<=2000; i++)
    {
        for(int j=0; j<26; j++)          //连续三个字符相等的
            for(int k=0; k<26; k++)
            {
                if(k==j) continue;
                dp[i][j]=(dp[i][j]+dp[i-3][k])%MOD;
            }
        for(int j=0; j<26; j++)          //连续两个字符相等的
            for(int k=0; k<26; k++)
            {
                if(k==j) continue;
                dp[i][j]=(dp[i][j]+dp[i-2][k])%MOD;
            }
        for(int j=0; j<26; j++)          //连续一个字符相等的
            for(int k=0; k<26; k++)
            {
                if(k==j) continue;
                dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;
            }
    }
}

int main()
{
    init();
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int ans=0;
        for(int i=0; i<26; i++)
            ans=(ans+dp[n][i])%MOD;
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-10-16 11:42  a_clown_cz  阅读(212)  评论(0)    收藏  举报