There is a straight highway with N storages alongside it labeled by 1,2,3,...,N. Bob asks you to paint all storages with two colors: red and blue. Each storage will be painted with exactly one color.
Bob has a requirement: there are at least M continuous storages (e.g. "2,3,4" are 3 continuous storages) to be painted with red. How many ways can you paint all storages under Bob's requirement?
Input
There are multiple test cases.
Each test case consists a single line with two integers: N and M (0<N, M<=100,000).
Process to the end of input.
Output
One line for each case. Output the number of ways module 1000000007.
Sample Input
4 3
Sample Output
3
题意:给长度为n的空间,每个空间可以涂成红色和蓝色,问有多少种方案满足有连续m个以上红色空间的方案。
思路:把红色用O蓝色用X表示好了,样例满足的条件就有三种:
OOOO
OOOX
XOOO
递推公式为dp[m]=1;
dp[i]=dp[i-1]*2+2^(i-m-1)-dp[i-m-1] (i>m)
当n刚好等于m的时候是只有一种情况,然后dp[i-1]*2,即是在之前满足的方案后面添O或X,不影响结果,后面是对没满足的情况进行处理,2^(i-m-1)是将i-m的位置涂成X之后i-m-1位置以前的所有满足或不满足情况,接着减去i-m-1之前的满足情况,即使i-m-1的不满足情况,加一个X和m个O,凑成满足情况
#include<stdio.h>
#include<string.h>
#define mod 1000000007
#define LL long long
LL pow[100005],dp[100005];
void init(){
pow[0]=1;
for(int i=1;i<=100000;i++)
pow[i]=pow[i-1]*2%mod;
}
int main(void){
init();
int n,m;
LL ans;
while(~scanf("%d",&n)){
memset(dp,0,sizeof(dp));
dp[m]=1;
for(int i=m+1;i<=n;i++)
dp[i]=((dp[i-1]*2%mod+pow[i-m-1]-dp[i-m-1])%mod+mod)%mod;
printf("%lld\n",dp[n]);
}
return 0;
}