2013 GDCPC J. Boring sequence

    题目不说了,大牛眼中的水题,我等水货想都想不到。。。

    直接贴代码,优化的面目全非。。。
    后来没有其他测试,只测试了题目中的几个样例以及1000 999之类的,不能保证代码完全正确,欢迎排错

/*
 * 定义 dp[i][j][0]为长度为i以j个0结尾的串的数量
 * 推出公式
 * dp[i][1][0]=sum(dp[i][k][1])(1<=k&&k<=K)
 * 优化过程为dp[i][j]=dp[i-1][j-1],即直接加一个与串末相同字符即可
 * 计算2的阶乘和计算和时,使用模运算
 * 因为dp[i][j][0]==dp[i][j][1],只有dp[i][1]有用
 * 继续优化空间
 * 发现最终的ans和dp[n+1]是一样的求法,故终极优化
 */
#include <iostream>
using namespace std;

const int MOD=1007;
const int maxn=1002;
int dp[maxn]={2,2};
int b[maxn]={0,1};

int main()
{
//  freopen("in.txt","r",stdin);
    for(int i=2;i<maxn;i++)
        b[i]=(b[i-1]*2) % MOD;

    int n,K;
    while(~scanf("%d%d",&n,&K))
    {
        n++;
        for(int i=2;i<=n;i++)
        {
            dp[i]=0;
            for(int k=1;k<=i-1&&k<=K;k++)
                dp[i]=(dp[i]+dp[i-k])%MOD;
        }
        printf("%d\n",(b[n]-dp[n]+MOD)%MOD);
    }
}

     由优化的代码产生的具象的想法:定义d[i]为连续相同字符长度不超过K的01字符串的个数,则d[i]可分为:

     d[i-1]:最后字符若为0,则添加1个1,反之为1,添加1个0。

     d[i-2]:最后字符若为0,则添加2个1,反之为1,添加2个0。

     ...

     d[i-k]:最后字符若为0,则添加k个1,反之为1,添加k个0。

     即 d[i] = sum(d[j])( max(1, i-k) <= j <= i-1)

     01串的题基本都是从最后开始递推,累加。优化方式有快速幂等。

     看了一下和以前做的杭电2604挺像,之前写的解题报告:http://www.cnblogs.com/IT-BOY/archive/2013/02/03/2890841.html

转载于:https://www.cnblogs.com/IT-BOY/archive/2013/05/13/3076442.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值