zoukankan      html  css  js  c++  java
  • Devu and Flowers

    题解

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

    2^n的状态,枚举某些花坛的花超过了,剩下的用隔板法计算个数,再加个容斥原理就行了

    ————————————————————————————————————————————-

    看来我应该写详细点

    首先隔板法sum个球放进n个盒子中允许盒子为空的方案是C(sum+n-1,n-1)

    但是由于这里有个限制,即f[i],这样计数的话某些花会超出其个数

    所以我们应该2^n枚举某些花超出了个数,比如确定i超出个数其它不确定的方案C(sum-f[i]-1+n-1,n-1)

    即sum-=f[i]+1(因为允许箱子为空一开始要人为加入一个球)

    这里再加个容斥原理+超0个的-超1个的+超2个的……

    还有要用到乘法逆元求C和lucas定理

    根据费马小定理a^(p-1)=1(mod p),a为质数

    a^(p-2)=a^(-1)(mod p),那么a^(p-2)就是a在modp意义下的逆元

    所以可以将C的公式上下分别得出取模后的乘积s1,s2,将s1乘s2的逆元

    lucas定理:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)

    前半部分继续递归用lucas定理,后半部分直接求

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    ll pow_mod(ll a,ll b) {
        ll res = 1;
        while (b) {
            if (b & 1) res = res * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return res;
    }
    
    ll C(int n,int m) {
        if (n < m) return 0;
        if (m > n - m) m = n - m;
        ll s1 = 1, s2 = 1;
        for (ll i = 0; i < m; i++) {
            s1 = s1 * (n - i) % mod;
            s2 = s2 * (i + 1) % mod;
        }
        return s1 * pow_mod(s2, mod - 2) % mod;
    }
    
    ll lucas(ll n,ll m) {
        if (m == 0) return 1;
        return C(n % mod, m % mod) * lucas(n / mod, m / mod) % mod;
    }
    
    int n;
    ll s,f[25];
    
    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 >> j & 1) {
                    sum -= f[j]+1;
                    sign *= -1;
                }
            }
            if (sum < 0) continue;
            ans += sign * lucas(sum + n - 1, n - 1);
            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
    ", solve());
        return 0;
    }
    

      

  • 相关阅读:
    redis/memcached可视化客户端工具TreeNMS
    Navicat Mysql快捷键
    mysql全文索引之模糊查询
    Discuz网警过滤关键词库
    php中的implements 使用详解
    PHP 依赖注入和控制反转再谈(二)
    php 中的closure用法
    C# 反射(Reflection)技术
    Oracle pl/sql编程值控制结构
    Oracle PL/SQL编程之变量
  • 原文地址:https://www.cnblogs.com/Accpted/p/11544680.html
Copyright © 2011-2022 走看看