zoukankan      html  css  js  c++  java
  • HDU 5201 The Monkey King

    题目大意:把n个桃子给m个不同的猴子,第一个必须拿严格最多,求方案数

    具体思路:首先考虑没有限制的情况,好像插个隔板就好了呢

    然后我们可以枚举第一个猴子的拿桃数,

    于是我们可以求出第一个猴子的拿桃数已知的总方案

    然后减去不合法的就好了

    怎么减勒?我们枚举有几个猴子拿的桃比大王多,然后用组合数求出有几种取法,在一顿乱搞就好了

    于是貌似重复了耶,结果发现如果有两个猴子拿的桃比大王多,这个情况会被在前面算2次,那么我们减掉

    如果有三个猴子拿的桃比大王多,这个情况会被在前面算0次,我们把它加上

    ...

    于是从1开始一个加一个减就好了(不会证)

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int ha=1000000007;
    int n,m,fact[200010],factinv[200010],inv[200010],ans,T;
    int INV(int x)
    {
        int ans=1,b=ha-2,a=x;
        while (b)
        {
            if(b&1)ans=ans*a%ha;
            b=b/2;a=a*a%ha;
        }
        return ans;
    }
    int C(int x,int y){return fact[x]*factinv[y]%ha*factinv[x-y]%ha;}
    int F(int x,int y){return C(x+y-1,y-1);}
    signed main()
    {
        fact[0]=1,factinv[0]=1,scanf("%lld",&T);
        for (register int i=1;i<=200000;i++)fact[i]=fact[i-1]*i%ha,inv[i]=INV(i),factinv[i]=factinv[i-1]*inv[i]%ha;
        while(T--)
        {
            scanf("%lld%lld",&n,&m),ans=F(n,m);
            for (register int i=0;i<=n;i++)
                for (register int j=1;j<=m&&i*(j+1)<=n;j++)(j%2)?ans=(ans-C(m-1,j)*F(n-i*(j+1),m-1)%ha+ha)%ha:ans=(ans+C(m-1,j)*F(n-i*(j+1),m-1)%ha)%ha;
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    一个简单的makefile,一次性编译本文件夹下所有的cpp文件
    c++ 最短路两种算法
    C++语言十进制数,CDecimal(未完成)
    C语言面向对象的简便方法
    C语言2048
    C图书借还示例
    Javascript 备忘
    原型与原型链
    css3动画-跳动圈
    学习css3动画
  • 原文地址:https://www.cnblogs.com/Orange-User/p/7751665.html
Copyright © 2011-2022 走看看