URAL2018——The Debut Album(DP)

                             G - The Debut Album

 
Pop-group “Pink elephant” entered on recording their debut album. In fact they have only two songs: “My love” and “I miss you”, but each of them has a large number of remixes.
The producer of the group said that the album should consist of  n remixes. On second thoughts the musicians decided that the album will be of interest only if there are no more than  a remixes on “My love” in a row and no more than  b remixes on “I miss you” in a row. Otherwise, there is a risk that even the most devoted fans won’t listen to the disk up to the end.
How many different variants to record the album of interest from  n remixes exist? A variant is a sequence of integers 1 and 2, where ones denote remixes on “My love” and twos denote remixes on “I miss you”. Two variants are considered different if for some  i in one variant at  i-th place stands one and in another variant at the same place stands two.
Input
The only line contains integers  nab (1 ≤  ab ≤ 300;  maxab) + 1 ≤  n ≤ 50 000).
Output
Output the number of different record variants modulo 10  9+7.
Example
input output
3 2 1
4

Notes

In the example there are the following record variants: 112, 121, 211, 212.

给你一个串的长度n,串由1,2组成,1连续不超过a个,2连续不超过b个,问有多少种这样的串,对1e9+7取模。

一看题就觉得记忆化可搞,几分钟就写出来了,奈何没考虑空间复杂度,ME。。
换了个思路,干脆两个DP,dp1[i]表示第i个为1的串的方案数,dp2[j]表示第j个为2的串的方案数。
状态转移方程dp1[i]+=dp2[i-j] dp2[i]+=dp1[i-j]  最后答案dp1[n]+dp2[n]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <stack>
using namespace std;
typedef long long ll;
#define PI 3.1415926535897932
#define E 2.718281828459045
#define INF 0xffffffff//0x3f3f3f3f
#define mod 1000000007
const int MOD=1e9+7;

const int M=1005;
int n,m;
int a,b;
int dp1[50001],dp2[50001];
int main()
{
    int i,j,k,t;
    int cas=0;
    int ans=0;
    //scanf("%d",&t);
    while(~scanf("%d%d%d",&n,&a,&b))
    {
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        dp1[0]=dp2[0]=1;
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=a&&j<=i; j++)
                dp1[i]=(dp1[i]+dp2[i-j])%MOD;
            for(j=1; j<=b&&j<=i; j++)
                dp2[i]=(dp2[i]+dp1[i-j])%MOD;
        }
        printf("%d\n",(dp1[n]+dp2[n])%MOD);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值