codeforces 554c[补]

    xiaoxiao2021-03-25  53

    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); } }
    转载请注明原文地址: https://ju.6miu.com/read-27365.html

    最新回复(0)