2015湘潭邀请赛 A.Coins

36 篇文章 0 订阅

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1233
题意:
n个影币,问有多少种情况至少连续m个正面朝上。
思路:
注意这道题是至少,而不是恰好,理解样例的时候刚开始在这个位置就出现了问题。
dp[i][0]表示满足条件的情况数量

dp[i][1]表示不满足条件的情况数量

注意在推到的时候有一个状态是i-1-m,这个状态是前i-1不满足情况且前i-1-m也不满足情况状态,这时连续的位置就是算上新更新的这个位置之后,也就是说它之前恰好有连续m-1个正面朝上,(第i-m个是反面朝上)注意情况不要重叠就ok了!算上新位置正好满足!

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1e6+10;
const LL MOD=1e9+7;
LL dp[N][2];
LL a[N];
int main()
{
    int t,i,j,n,m;
    a[0] = 1;
    for(i = 1; i<N; i++)
        a[i] = ((LL)2*a[i-1])%MOD;//n个硬币一共有n^2个状态
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        dp[m][0] = 1;//初始值,只有m个硬币呢么必须全部面朝上,只有1种
        dp[m][1] = (a[m]-dp[m][0]+MOD)%MOD;//总方案数减去面朝上的方案数为不可行的
        for(i = 0; i<m; i++)//不足m个,则为全状态
            dp[i][1] = a[i];
        for(i = m+1; i<=n; i++)
        {
            /*
            i个满足的状况首先从i-1个枚举来,i-1的状态满足的话,那么再加一个硬币可正可反,所以dp[i-1][0]*2
            然后还要加上dp[i-1-m][1],这是对于连续m个面朝上看做一个整体,然后包括剩下不可行的方案数
            */
            dp[i][0] = ((dp[i-1][0]*2+MOD)+dp[i-1-m][1])%MOD;
            dp[i][1] = (a[i]-dp[i][0]+MOD)%MOD;
        }
        printf("%I64d\n",dp[n][0]);
    }

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值