玲珑杯 Black and White 【dp】

1091 - Black and White

Time Limit:4s Memory Limit:128MByte

Submissions:246Solved:78

DESCRIPTION

Constroy likes the game called Reversi. He has a long paper tape with nn grids, where each grid should fill by one black chess or one white chess exactly. Constroydislikes the situation with aa consecutive black chesses or bb consecutive white chesses, so he intends to know how many situaions satisfy his preference.

The answer may be so large, but you only need to give the answer modulo (109+7)(109+7).

INPUT
The first line contains a positive integer TT, which represents there are TT test cases.The following is test cases. For each test case:The only one line contains three integers a,ba,b and nn.It is guaranteed that no more than 50 test cases satisfy n104n≥104. 1T103,1a,b,n1061≤T≤103,1≤a,b,n≤106
OUTPUT
For each test case, output in one line, contains one integer, which represents the number of situations satisfy his preference modulo (109+7)(109+7).
SAMPLE INPUT
101 1 22 3 34 6 55 6 44 5 68 1 99 1 89 9 1016 16 161000000 1000000 1000000
SAMPLE OUTPUT
0429165301101865534235042057


明显是要dp的
考虑d[i][j]=长度为i的棋盘 最后一个棋子为j颜色的合法方案数 j=0,1
单独考虑d[i][0]
明显 d[i-1][1]后加一个0可以得到合法序列
d[i-1][0]后直接加0 可能出现xxxx1 + a个0 这种不合法情况
而这种情况 = d[i-a][1] :即xxxx1 的方案数
so: d[i][0] = d[i-1][1] + d[i-1][0] - d[i-a][1]


这题真正坑的地方是 i==0时
显然应该把空串看做一个串 但是d[0][0]=d[0][1]=1
就变成了空串有2个串
只好特判一下

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
#include<queue>
#include<sstream>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
#define pll pair<ll,ll>
#define pid pair<int,double>

const int N = 1e6+5;
const int MOD = 1e9+7;
int a,b,n;
int d[N][2];//d[i][j]=前i个棋子,第i个棋子颜色为j的合法方案数
int dp(){
    d[0][1]=d[0][0]=0;
    for(int i=1;i<=n;++i) {
        int sum = (d[i - 1][0] + d[i - 1][1]) % MOD;
        if(i==1){
            sum=1;
        }
        d[i][0]=d[i][1]=sum;
        if(i-a>=0){
            d[i][0] = (d[i][0] - d[i-a][1] - (i==a) + MOD)%MOD;//i==a表示空串的情况
        }
        if(i-b>=0){
            d[i][1] = (d[i][1] - d[i-b][0] - (i==b) + MOD)%MOD;
        }
    }
    return (d[n][0]+d[n][1])%MOD;
}

int main()
{
    //freopen("/home/lu/Documents/r.txt","r",stdin);
    //freopen("/home/lu/Documents/w.txt","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&a,&b,&n);
        printf("%d\n",dp());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值