Coins | ||
Accepted : 66 | Submit : 167 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
CoinsProblem 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. InputThe 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.() OutputFor each test case, output the result modulo in one line. Sample Input2 Sample Output8 SourceXTU OnlineJudge |
/*
题意:有N个硬币,每个硬币是正面或者反面朝上。问存在多少种方案,使得存在连续M个正面朝上的硬币。
思路:dp[i]表示前i个硬币满足条件的方案数,dp[i] = 2 * dp[i - 1] + (2^(i - m - 1) - dp[i - m - 1]):
分两种情况:
①当第i位对约束无关紧要(即前i-1位已经满足约束),那么这种情况对答案的贡献为2 * dp[i - 1];
②当第i位对约束是关键的(即前i-1位并不满足约束),那么[i-m+1,m]上的硬币一定正面朝上,且第m个硬币一定反面朝上,对答案的贡献为(2^(i - m - 1) - dp[i - m - 1];
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010;
const int mod = 1000000007;
long long p2[N], dp[N];
void solve() {
int n, m;
scanf("%d%d", &n, &m);
memset(dp, 0, sizeof(dp));
dp[m] = 1;
for (int i = m + 1; i <= n; i++) {
dp[i] = (2 * dp[i - 1] + p2[i - m - 1] - dp[i - m - 1]) % mod;
if (dp[i] < 0) dp[i] += mod;
}
printf("%d\n", (int)dp[n]);
}
int main()
{
p2[0] = 1;
for (int i = 1; i < N; i++) p2[i] = p2[i - 1] * 2 % mod;
int t;
scanf("%d", &t);
while (t--) solve();
return 0;
}