HDU5201 The Monkey King

题意:m个猴子分n个桃子要求第一个猴子的桃子最多,问有几种方案

题解:没有想到更好的方法,只能用容斥,枚举第一个猴子的桃子数x,剩下的m-1个猴子分n-x个桃子,要求剩下的每一个猴子的桃子数小于第一个,1个猴子小于方案数-2个猴子小于方案数+。。。

复杂度nlogn

#include <bits/stdc++.h>
#define maxn 201000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
ll a[maxn], b[maxn], mod = 1e9+7;
ll power(ll x,ll t,ll mod){
    ll ans=1;
    x %= mod;
    while(t){
        if(t&1) ans = ans*x%mod;
        x = x*x%mod;
        t >>= 1;
    }
    return ans;
}
void init(){
    a[0] = b[0] = 1;
    for(ll i=1;i<maxn;i++) a[i] = a[i-1]*i%mod;
    for(ll i=1;i<maxn;i++) b[i] = power(a[i], mod-2, mod);
}
ll c(ll n,ll m){
    return a[n]*b[m]%mod*b[n-m]%mod;
}
ll f(ll n,ll m){
    return c(n+m-1, n);
}
int main(){
    init();
    ll n, m, ans=0, T, temp;
    scanf("%lld", &T);
    while(T--){
        scanf("%lld%lld", &n, &m);
        if(n == 1||m == 1){
            printf("1\n");
            continue;
        }
        ans = 0;
        for(int i=1;i<=n;i++){
            if((i-1)*(m-1)<n-i) continue;
            if((n-i)/(m-1)>i) continue;
            ans += f(n-i, m-1);
            for(int j=1;n-i*(j+1)>=0;j++){
                temp = c(m-1, j)*f(n-i*(j+1),  m-1)%mod;
                if(j%2 == 0) ans = (ans+temp)%mod;
                else ans = (ans-temp+mod)%mod;
            }
        }
        printf("%lld\n", (ans+mod)%mod);
    }
    return 0;
}

 

posted on 2017-10-19 16:25  2855669158  阅读(98)  评论(0编辑  收藏  举报

导航