codeforces 554c[补]

BNUZ比赛训练【补】

感觉自己最近真的是菜不行了,拿到这题,读了5分钟题目读懂了,然后就在想组合数学,当时是完全不记得组合数学的插入法。。一直想着应该有公式,然后凭印象写了两三条,不记得了。。就直接跳过这题了,后来看到队友在模拟插入。。灵光一想,对啊,可以这样敲,然后就开始先打了个排列组合的表,比赛结束还有5分钟,然后随手敲了敲自己思路。。然后发现样例过不了。然后就放弃了。。


题目:http://codeforces.com/problemset/problem/554/C
题目大致:
给你n钟颜色的球,每个球的数量为ai个,要求,颜色大的球从后往前看的时候必须先出现,也就是说,如果5这种颜色的球没出现,4 3 2 1这四种球都不能出现。明显就是一道组合数学。。


赛后。
一大一新生说,哇我赛后一分钟DP过了这题,然后我蒙了下,DP?怎么可能用DP。。哪里有DP的想法。。跑去一看他代码,跟我的不是长得一样(他所谓的DP就是组合数学的打表。。)。等等。。我的代码敲错了,应该从后往前,然而我从前往后。答案打死出不来。。我的天orz

思路:
先把所有球的个数统计出来,表示有sum个位置要填写球,然后从后往前看,每次先花费一个球,占住一个最后的位置,然后其他球排列组合随意放就有C[ai - 1][sum - 1]这么多种排列组合方式,然后将每次的排列组合方式都乘起来就好了,每次运算完后sum得要减去ai的球数。

再次贴上菜鸡代码

/*
@rescoues: codeforces 554c
@date: 2017-3-10
@author: QuanQqqqq
@algorithm: 组合数学 
*/
#include <bits/stdc++.h>

#define MAXN 1005
#define INF 0x3f3f3f
#define ll long long
#define MOD 1000000007

using namespace std;

ll f[MAXN][MAXN],total[MAXN];
ll n,sum,ans;

int main(){
    for(ll i = 1;i < MAXN;i++){
        f[1][i] = i;
        f[0][i] = 1;
    }
    for(ll i = 2;i < MAXN;i++){
        f[i][i] = 1;
        for(ll j = i + 1;j < MAXN;j++){
            f[i][j] = (f[i][j - 1] + f[i - 1][j - 1]) % MOD;
        }
    }
    while(~scanf("%lld",&n)){
        sum = 0;
        for(ll i = 1;i <= n;i++){
            scanf("%lld",&total[i]);
            sum += total[i];
        }
        ans = 1;
        for(ll i = n;i >= 2;i--){
            if(total[i]){
                ans = (ans * f[total[i] - 1][sum - 1]) % MOD;
                sum -= total[i];
            }
        }
        printf("%lld\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值