cf 553A dp+组合数学

题意:
有K中颜色去涂球,第i中颜色要涂ci个球,不能位置的球颜色相同是有区别的,涂完第i种球的时候前i-1种球必须先涂完,问总共有多少种涂法

分析:
一开始想按涂球的数量递推,然后发现是不行的,复杂度太大
这题怎么想呢,按已涂的颜色数量来递推。
怎么想呢?
假设我们已经涂了前i-1种颜色的球,并且种类为dp[i-1],并且前i-1中颜色的球的总数是presum,这个时候我们要涂第i中颜色的ci个球,这就相当于把ci-1个球插入到presum个球中间去,并且把最后一个放到最后,那么dp[i] = dp[i-1] * C(ci-1+presum,ci-1)

AC代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const long long MOD = 1000000007;

long long f[1100], fe[1100];
long long dp[1100];
int K, num[1100];

long long getf( long long x ){
    long long ans = 1, temp = MOD - 2;
    while( temp ){
        if( temp & 1 ){
            ans = ans * x % MOD;
        }
        x = x * x % MOD;
        temp /= 2;
    }
    return ans;
}

void init(){
    f[0] = f[1] = 1;
    fe[0] = fe[1] = 1;
    for( int i = 2; i <= 1000; i++ ){
        f[i] = f[i-1] * i % MOD;
        fe[i] = fe[i-1] * getf( i ) % MOD;
    }
}

int main(){
    init();
    scanf( "%d", &K );
    for( int i = 0; i < K; i++ ){
        scanf( "%d", &num[i] );
    }
    dp[0] = 1;
    int presum = num[0];
    for( int i = 1; i < K; i++ ){
        dp[i] = dp[i-1] * f[presum + num[i]-1] % MOD * fe[num[i]-1] % MOD * fe[presum] % MOD;
        presum += num[i];
    }
    printf( "%I64d\n", dp[K-1] );
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值