xtuoj 1233 coins(dp)

Coins

Accepted : 120   Submit : 305
Time Limit : 1000 MS   Memory Limit : 65536 KB

 

Coins

Problem Description:

Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face on. And Duoxida wants to know how many situations that m continuous coins head face on among all possible situations. Two situations are considered different if and only if there is at least one position that the coins' faces are different.

Input

The first line contains a integer T(no more than 20) which represents the number of test cases.

In each test case, a line contains two integers n and m.(\\(0 < m \\le n \\le 10^6\\))

Output

For each test case, output the result modulo \\(10^9+7\\) in one line.

Sample Input

2
4 2
5 2

Sample Output

8
19


Source

XTU OnlineJudge 

 


 

这题的话dp起来还是比较简单的。

dp[0][i]代表不满足情况下长度为i的硬币串数量。

dp[1][i]代表满足情况下长度为i的硬币串数量。

对于i<m 显然所有状态都不满足连续m个硬币正面朝上,d[0][i]=2^i,dp[1][i]=0;

对于i=m 那么只有一种情况连续m个硬币正面朝上,d[0][i]=2^i-1,dp[1][i]=1;

对于i>m,对于满足的情况,考虑到所有状况并且为了避免状况重复,他可以从i-1长度下满足的情况下,在i位置添加一个任意面得到i长度下满足的情况;也能从i-m-1长度的不满足的情况下,在其之后添加一个反面朝上,然后添加m个正面朝上来得到i长度下满足的情况,注意这样的情况是最长长度为m,并且连续的长度最后一位在i位置,与前一种方式的出来的情况没有重复部分。而且两者包含所有的满足的情况,所以,dp[1][i]=dp[1][i-1]*2+dp[0][i-m-1]。不满足的情况即为所有状态减去满足的情况:dp[0][i]=2^i-dp[1][i]。因此此题只要O(n)即能dp得出答案。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring> 
 4 #define clr(x) memset(x,0,sizeof(x))
 5 #define LL long long 
 6 #define MOD (1000000007)
 7 using namespace std;
 8 LL dp[2][1000010];
 9 LL pow[1000010];
10 int main()
11 {
12     int n,m;
13     int T;
14     scanf("%d",&T);
15     pow[0]=1;
16     for(int i=1;i<=1000000;i++)
17     {
18         pow[i]=(pow[i-1]*2)%MOD;
19     }
20     while(T--)
21     {
22         scanf("%d%d",&n,&m);
23         for(int i=0;i<=m;i++)
24         {
25             dp[1][i]=0;
26             dp[0][i]=pow[i];
27         }
28         dp[1][m]=1;
29         dp[0][m]=pow[m]-dp[1][m];
30         for(int i=m+1;i<=n;i++)
31         {
32             dp[1][i]=(dp[1][i-1]*2+dp[0][i-m-1])%MOD;
33             dp[0][i]=((pow[i]-dp[1][i])%MOD+MOD)%MOD;
34         }
35         printf("%lld\n",dp[1][n]);
36     }
37     return 0;
38  } 
dp

 

posted @ 2017-05-16 10:53  hk_lin  阅读(278)  评论(0编辑  收藏  举报