BestCoder Round #75 T3 King's Order HDOJ 5642

来源:互联网 发布:程序员能自学吗 编辑:程序博客网 时间:2024/05/01 15:17

/*
这道题看起来似乎可以用公式的样子,但实际上在不断地尝试过之后发现并不可以。。。
所以我们考虑动态规划,方程dp[i]表示考虑到第i位时合法解的数量,利用第i-1位的情况动态地刷新出第i位的情况。
但是。。。。
该怎么转移呢?╭(╯^╰)╮。。。
下面我们来考虑一下这个转移的特点:如果对命令没有要求,那么答案就是26的n次方,那么就这样:dp[i]=dp[i-1]*26-非法情况。所以我们来考虑对于非法情况该如何转移;
由于国王的命令最多也只能有三个字母相连,所以在所有的情况中,如果前三个字符已经相同,那当前这一位就受到了限制,那这个限制究竟是多少呢?
关键在于在所有的情况中有多少情况会在末尾出现三连呢?那么关键来了!
让我们回到4位之前(i-4),假设这时候i-4位有x种合法情况,那么到当前这一位中的那决定性的三位以a为三连结尾的就有x种,同理,b,c,d……都有x种那么就减去dp[i-4]*26喽!
可是这是错的!因为第i-5位还有一个字母呢,要是乘以26的话那不就出现4连了么?所以真实的情况是乘以25~~~;
*/

#include<iostream>#include<algorithm>#include<queue>#include<cstdio>#include<cstring>using namespace std;//全程long long,全程long long ,全程long long!!!typedef long long ll;ll T,n,mod=1e9+7,dp[2010];int main(){        cin>>T;        dp[1]=26;        dp[2]=26*26;        dp[3]=26*26*26;        dp[4]=456950;        /*        这里要注意,我们的方法对于n=4可是不行的,所以直接把4算出来,很明显不能4连,4的答案就是26*26*26*26-26(这里把dp[0]初始化成1是不行滴,应该减26);        */        for(int i=5;i<=2000;i++)        {                dp[i]=((26ll*dp[i-1]-dp[i-4]*25ll)%mod+mod)%mod;//这里有个重要的细节,为什么我们要%一次又加一个mod再%一次呢?如果只%一次不加的话,就有可能会减出负数!(事实证明的确如此)        }//为了节省时间,我们直接把1-2000全算出来,询问时直接查询就好啦;        while(T--)        {                scanf("%d",&n);                printf("%I64d\n",dp[n]%mod);        }}
0 0
原创粉丝点击