【BNU Summer Training 2014.07.25】 Painting Storages (dp)


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

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


首先不能使用二维dp,因为n,m为100000,空间大小会超.


dp[i]表示n==i时满足条件的涂色方案数.

故for(int i=1;i

dp[m]=1;

当i>m时,考虑前i-1个物体的染色情况:

1.前i-1个物体满足条件时,最后一个涂色随意,故共 2*dp[i-1] 种;

2.前i-1个物体不满足条件时,则最后一个一定要为red,且前i-1个物体中最后连续m-1个物体也是red,且前i-1个物体中倒数第m个物体一定是blue,且前i-m-1个物体不满足条件;故方案数为: pow(2,i-m-1)-dp[i-m-1] 种;

综上,

dp[i]=2*dp[i-1]+pow(2,i-m-1)-dp[i-m-1]

附上代码:

# include 
# include 
# define p 1000000007
long long  dp[100100];

long long _pow (long long  a,int  n)
{
    long long  r=1;
    while (n)
    {
        if(n%2==1)
        {
            r=((r%p)*a)%p;
            n=n-1;
        }
        a=((a%p)*(a%p))%p;
        n=n/2;

    }
    return r%p;
}

int main ()
{
    int n,m,i,j;
    long long ans;
    while(scanf("%d",&n)!=EOF)
    {
        scanf("%d",&m);
        for(i=0;i




你可能感兴趣的:(dp,dp)