zoukankan      html  css  js  c++  java
  • 【codeforces 768F】Barrels and boxes

    【题目链接】:http://codeforces.com/problemset/problem/768/F

    【题意】

    让你把f个food和w个wine装在若干个栈里面;
    每个栈只能装food或者是wine;
    且装wine和food的栈交替出现;
    然后是随机等可能地分配方案;
    问你wine的栈里面,wine的数量都大于h的概率是多少;

    【题解】

    可以把一个栈里面的东西看成是线性的;
    即如果某个栈里面有3个food;
    就相当于3个food排成了一排;
    这样,原问题等价于;
    有f个food放在直线上;
    然后有f+1个位置可以放wine;
    这f+1个位置中,每个位置放置的wine的数量都必须多于h个;
    则先从这f+1个位置中选出i个位置
    C(f+1,i)
    然后先把这i个位置都放h个wine;
    则剩余rest=w-h*i个wine;
    然后相当于解一个方程
    x1+x2+…+xi=rest且x1,x2..xi都是正整数;
    求它的不同解个数;
    高中数学题。隔板法;
    答案就为
    C(rest1,i1)
    枚举i的时候答案递增
    C(f+1,i)C(whi1,i1)
    这样就能把分子算出来了;
    而分母是
    C(f+w,w)
    即随便选w个位置放wine,其他地方放food就是了;
    写个乘法逆元;
    然后注意边界,即w=0的时候,这时候是没有wine的了;
    所以不存在说wine会小于等于h的情况,即任何方案都可行;
    有个f+w,所以阶乘得算到2*1e5….

    【Number Of WA

    4

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    #define Open() freopen("F:\rush.txt","r",stdin)
    #define Close() ios::sync_with_stdio(0),cin.tie(0)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 2e5+100;
    const LL MOD = 1e9+7;
    
    LL fac[N+100],rfac[N+100];
    LL f,w,h;
    
    LL ksm(LL x,LL y)
    {
        LL t = 1;
        while (y)
        {
            if (y&1) t = (t*x)%MOD;
            x = (x*x)%MOD;
            y>>=1;
        }
        return t;
    }
    
    void pre()
    {
        fac[0] = 1;
        rep1(i,1,N) fac[i] = (fac[i-1]*i)%MOD;
        rfac[N] = ksm(fac[N],MOD-2);
        rep2(i,N,1) rfac[i-1] = (rfac[i]*i)%MOD;
    }
    
    LL C(LL n,LL m)
    {
        //n!/(n-m!)*m!
        return (fac[n]*rfac[n-m]%MOD)*rfac[m]%MOD;
    }
    
    int main()
    {
        //Open();
        Close();//scanf,puts,printf not use
        //init??????
        pre();
        cin >> f >> w >> h;
        LL fz = 0;
        for (LL i = 1;i <= f+1;i++)
        {
            if ((h+1)*i>w) break;
            fz = fz+C(f+1,i)*C(w-h*i-1,i-1)%MOD;
            fz%=MOD;
        }
        LL fm = C(f+w,w);
        if (w==0) fz = fm;
        LL ans = fz*ksm(fm,MOD-2)%MOD;
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    C语言打印记事本内搜索字符串所在行信息
    原创:C语言打开、下载、删除网页,统计网页字符个数
    JAVA GUI编程学习笔记目录
    13.JAVA之GUI编程将程序打包jar
    12.JAVA之GUI编程打开与保存文件
    11.JAVA之GUI编程菜单
    10.JAVA之GUI编程弹出对话框Dialog
    php中的一些不常见的问题foreach/in_array[开发篇]
    微软职位内部推荐-Senior SDE
    微软职位内部推荐-SDE II
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626304.html
Copyright © 2011-2022 走看看