串串

版权声明:未经过同意不得转载 https://blog.csdn.net/qq_42500298/article/details/83108068

题目描述

给定非负整数a,b,c,d,求有多少对01串(S,T),满足以下条件: - S 由 a 个 0 , b 个 1 组成 - T 由 c 个 0 , d 个 1 组成 - T 可以由 S 删掉一些字符得到 由于答案可能过大,你只需要输出答案对 1000000007 取模后的值

输入描述:

第一行四个非负整数 a , b , c , d对于 的数据,有a,b,c,d≤ 3对于 的数据,有a,b,c,d≤ 50对于 的数据,有a,b,c,d≤ 300另有 的数据,有 c=0对于 的数据,有0≤ a,b,c,d≤ 2000,且0≤ c≤ a,0≤ d≤ b,a+b≥ 1,c+d≥ 1

输出描述:

输出一个非负整数表示答案

示例1

输入

2 1 1 1

输出

4

说明

(001,01) , (010,10),(010,01) , (100,10)

思路

t 是从 s 中删除一些字符得到的,t 一共有 C(c+d,c) 种,考虑逆过程,我们 在 t 上面插入 a-c 个 0,b-d 个 1 来得到 s
可以枚举末尾有几个 0 几个 1,然后用插板法统计方案。
代码里还有一些要注意的地方

代码

include<bits/stdc++.h>
using namespace std;
const long long MOD=1e9+7;
const long long N=5005;
long long C[N][N];
long long calc(long long x,long long y)//x放入y个东西里面 
{
    if(x==0) 
  return 1;
    if(y<=0) 
  return 0;
    return C[x+y-1][y-1];
}
int main()
{
    C[0][0]=1;
    for(long long u=1;u<=5000;u++)
    {
        C[u][0]=1;
        for(long long i=1;i<=u;i++)
            C[u][i]=(C[u-1][i-1]+C[u-1][i])%MOD;
    }
    long long a,b,c,d;
    scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
    a=a-c;b=b-d;
    long long ans=0;//枚举末尾有i个0,j个1
    for(long long u=0;u<=a;u++)
    {
        for(long long i=0;i<=b;i++)//放在最后面有多少个 
        {
            long long x=a-u,y=b-i;
            ans=(ans+C[u+i][u]*calc(y,c)%MOD*calc(x,d)%MOD)%MOD;
        }
    }
    ans=ans*C[c+d][d]%MOD;
    printf("%lld\n",ans);
    return 0;
}

来源:nkw

猜你喜欢

转载自blog.csdn.net/qq_42500298/article/details/83108068
今日推荐