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; }

浙公网安备 33010602011771号