ZOJ 3747 Attack on Titans 带限制的递推DP

Attack on Titans ZOJ - 3747

总共有 nn 个人,编号 1n1\sim n,三个种类 A,B,CA,B,C,要求有连续不少于 mmAA 种类的人,连续不多于 kkBB 种类的人,问这 nn 个人的有多少种组合方式?

思路参考 https://blog.csdn.net/wust_ZJX/article/details/46809951

难以处理至少问题,因此要把至少转换成至多,设事件 D={D=\{ 至多 nnAA,至多 kkBB }\},事件 E={E=\{ 至多 m1m-1AA,至多 kkBB }\},则 DE={D-E=\{ 至少 mmAA,至多 kkB }B\ \},即为最终答案。现在考虑至多 uuAA,至多 vvBB,令 dp[i][0],dp[i][1],dp[i][2]dp[i][0],dp[i][1],dp[i][2] 分别表示位置 ii 放种类 A,B,CA,B,C 对应的组合数,令 sum=dp[i1][0]+dp[i1][1]+dp[i1][2]sum=dp[i-1][0]+dp[i-1][1]+dp[i-1][2], 则对于种类 AA 而言:

(1)iui\le u 时,仍在限制之内:

dp[i][0]=sum dp[i][0]=sum

(2)i=u+1i=u+1 时,要减去 1u1\sim u 这一段为 AA 类对应的组合数,有一种:

dp[i][0]=sum1 dp[i][0]=sum-1

(3)i>u+1i>u+1 时,则要减去 iui1i-u\sim i-1 这一段为 AA 类对应的组合数:

dp[i][0]=sumdp[iu1][1]dp[iu1][2] dp[i][0]=sum-dp[i-u-1][1]-dp[i-u-1][2]

对于种类 BB 同理有:

(1)ivi\le v 时,仍在限制之内:

dp[i][1]=sum dp[i][1]=sum

(2)i=v+1i=v+1 时,要减去 1v1\sim v 这一段为 BB 类对应的组合数,有一种:

dp[i][1]=sum1 dp[i][1]=sum-1

(3)i>v+1i>v+1 时,则要减去 ivi1i-v\sim i-1 这一段为 BB 类对应的组合数:

dp[i][1]=sumdp[iv1][0]dp[iv1][2] dp[i][1]=sum-dp[i-v-1][0]-dp[i-v-1][2]

由于 CC 类不影响限制条件,因此有:

dp[i][2]=sum dp[i][2]=sum

代码如下:

#include<iostream>
#include<cstdio>
//#define WINE
#define MOD 1000000007
#define MAXN 1000005
using namespace std;
typedef long long ll;
ll n,m,k,dp[MAXN][3],sum;
ll f(ll u,ll v){
    dp[0][0]=dp[0][1]=0;dp[0][2]=1;
    for(int i=1;i<=n;i++){
        sum=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])%MOD;
        if(i<=u)dp[i][0]=sum;
        else if(i==u+1)dp[i][0]=(sum-1+MOD)%MOD;
        else dp[i][0]=((sum-dp[i-u-1][1]-dp[i-u-1][2])%MOD+MOD)%MOD;
        if(i<=v)dp[i][1]=sum;
        else if(i==v+1)dp[i][1]=(sum-1+MOD)%MOD;
        else dp[i][1]=((sum-dp[i-v-1][0]-dp[i-v-1][2])%MOD+MOD)%MOD;
        dp[i][2]=sum;
    }
    return (dp[n][0]+dp[n][1]+dp[n][2])%MOD;
}
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    while(scanf("%lld%lld%lld",&n,&m,&k)!=EOF)
        printf("%lld\n",((f(n,k)-f(m-1,k))%MOD+MOD)%MOD);
    return 0;
}

在这里插入图片描述

posted @ 2020-03-28 08:25  winechord  阅读(97)  评论(0编辑  收藏  举报