您的位置:首页 > 其它

2015湘潭邀请赛 A.Coins

2016-02-15 11:13 309 查看
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
[2];
LL a
;
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
[0]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  湘潭