Codeforces 451E Devu and Flowers 容斥原理

本文详细解析了Codeforces451E题目“Devu and Flowers”的解题思路,利用状态压缩和容斥原理,通过隔板法计算选取特定数量花朵的不同组合方式。
               

题目链接:Codeforces 451E Devu and Flowers

题目大意:有n个花坛,要选s支花,每个花坛有f[i]支花。同一个花坛的花颜色相同,不同花坛的花颜色不同,问说可以有多少种组合。

解题思路:2n的状态,枚举说那些花坛的花取超过了,剩下的用C(n−1sum+n−1)隔板法计算个数,注意奇数的位置要用减的,偶数的位置用加的,容斥原理。

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long ll;//ll n, m, p;ll qPow (ll a, ll k, ll p) {    ll ans = 1;    while (k) {        if (k&1)            ans = (ans * a) % p;        a = (a * a) % p;        k /= 2;    }    return ans;}ll C (ll a, ll b, ll p) {    if (a < b)        return 0;    if (b > a - b)        b = a - b;    ll up = 1, down = 1;    for (ll i = 0; i < b; i++) {        up = up * (a-i) % p;        down = down * (i+1) % p;    }    return up * qPow(down, p-2, p) % p; // 逆元}ll lucas (ll a, ll b, ll p) {    if (b == 0)        return 1;    return C(a%p, b%p, p) * lucas(a/p, b/p, p) % p;}const int maxn = 25;const ll mod = 1e9+7;int n;ll s, f[maxn];ll solve () {    ll ans = 0;    for (int i = 0; i < (1<<n); i++) {        ll sign = 1, sum = s;        for (int j = 0; j < n; j++) {            if (i&(1<<j)) {                sum -= (f[j]+1);                sign *= -1;            }        }        if (sum < 0)            continue;        ans += sign * lucas(sum + n - 1, n - 1, mod);        ans %= mod;    }    return (ans + mod) % mod;}int main () {    scanf("%d%lld", &n, &s);    for (int i = 0; i < n; i++)        scanf("%lld", &f[i]);    printf("%lld\n", solve());    return 0;}
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值