hdu 5642 (递归)

来源:互联网 发布:闪电seo 编辑:程序博客网 时间:2024/06/06 01:43

题目大意

国王演讲后士气大增,但此时战争还没有结束,国王时不时要下发命令。由于国王的口吃并没有治愈,所以传令中可能出现:“让第三军-军-军,到前线去” 这样的命令。由于大洋国在军队中安插了间谍 , 战事紧急,很多时候前线的指挥官不能分清哪些命令真正来自国王。但国王的命令有一个特点,他每次连续重复的字符最多 33 次. 所以说他的命令中没有:“让第三军-军-军-军 , 到前线去”,但是可以有 :“让第三军-军 , 到前线去” 。此时将军找到了你,你需要告诉他,给定命令的长度长度为 nn,有多少种不同的命令可以是国王发出的 。(也就是求长度为 nn 的合格字符串的个数)当然,国王可能说出一句话没有犯任何口吃,就像他那次演讲一样。为了简化答案,国王的命令中只含有小写英文字母,且对答案输出模 10000000071000000007。我们认为两个命令如果完全相同那么这两个字符串逐个比较就完全相同。
这题的思路就是递归:

dp[i][j]表示国王说的第I个字有j个是重复的。j可以等于 0,1,2,3;j=0表示为第i个字一共有多少种可能。

所以有公式

 dp[i][1]=(dp[i-1][1]*25+dp[i-1][2]*25 +dp[i-1][3]*25)%md;
 dp[i][2]=dp[i-1][1];
 dp[i][3]=dp[i-1][2];

AC 代码:

/* ***********************************************Author        :yzkAcceptedCreated Time  :2016/3/12 20:13:34TASK          :lol.cppLANG          :C++************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef __int64 ll;const int md=1000000007;int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    ll dp[2500][4];    int t;    scanf("%d",&t);    memset(dp,0,sizeof(dp));    dp[1][0]=26;    dp[1][1]=26;    dp[1][2]=0;    dp[1][3]=0;    for(int i=2;i<=2000;i++)    {        dp[i][1]=(dp[i-1][1]*25+dp[i-1][2]*25 +dp[i-1][3]*25)%md;        dp[i][2]=dp[i-1][1];        dp[i][3]=dp[i-1][2];        dp[i][0]=(dp[i][1]+dp[i][2]+dp[i][3])%md;    }    while(t--)    {        int k;        scanf("%d",&k);        printf("%I64d\n",dp[k][0]);    }    return 0;}


0 0
原创粉丝点击