• Codeforces Round #258 (Div. 2)E


    题意:n<20个箱子,每个里面有fi朵颜色相同的花,不同箱子里的花颜色不同,要求取出s朵花,问方案数
    题解:假设不考虑箱子的数量限制,隔板法可得方案数是c(s+n-1,n-1),当某个箱子里的数量超过fi时,方案数是c(s-f[i]-1+n-1,n-1),容斥原理求,状压枚举哪几个箱子超过了f[i],答案就是超过0个-超过1个+超过2个...
    由于c(n,m)的m很小,直接暴力求解

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    //#include <bits/extc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define mt make_tuple
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    //#define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define bpc __builtin_popcount
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    #define mr mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    //using namespace __gnu_pbds;
    
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f;
    
    ll s,a[30],inv[30];
    ll c(ll a,ll b)
    {
        ll ans=1;
        for(ll i=a;i>=a-b+1;i--)ans=ans*(i%mod)%mod;
        return ans*inv[b]%mod;
    }
    int main()
    {
        inv[0]=1;
        for(int i=1;i<30;i++)inv[i]=inv[i-1]*qp(i,mod-2)%mod;
        int n;
        scanf("%d%lld",&n,&s);
        for(int i=0;i<n;i++)scanf("%lld",&a[i]);
        ll ans=0;
        for(int i=0;i<(1<<n);i++)
        {
            int f=0;
            ll sum=0;
            for(int j=0;j<n;j++)if((i>>j)&1)
            {
                sum+=a[j]+1;
                f^=1;
            }
            if(sum>s)continue;
            if(!f)add(ans,c(s-sum+n-1,n-1));
            else sub(ans,c(s-sum+n-1,n-1));
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /********************
    
    ********************/
    
  • 相关阅读:
    【每天一道PAT】1001 A+B Format
    C++ STL总结
    开篇
    happen-before原则
    java多线程的状态转换以及基本操作
    集合初始容量
    fail-fast机制
    Stack
    Iterator
    Vector
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10873914.html
Copyright © 2020-2023  润新知