BestCoder Round #75 T3 King's Order HDOJ 5642

本文探讨了一种使用动态规划解决特定字符串限制问题的方法。针对国王禁止三个连续相同字母的问题,通过逐步推导,给出了一个有效的算法实现。该算法考虑了状态转移的特点,并通过巧妙的数学运算避免了非法状态的产生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
这道题看起来似乎可以用公式的样子,但实际上在不断地尝试过之后发现并不可以。。。
所以我们考虑动态规划,方程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);
        }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值