zoukankan      html  css  js  c++  java
  • 排列组合的去重问题

    题目描述

    给出四堆石子,石子数分别为a,b,c,d。规定每次只能从堆顶取走石子,问取走所有石子的方案数。
     
     
     
     
     
     

    输入描述:

    在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数>

    输出描述:

    输出一个整数表示答案,答案对109+7取模

    输入

    3 5 4 2

    输出

    2522520

    备注

    输入均为不超过500的正整数


    题意:每次只能取一颗石子,然后有多少种不同的取石子方法,其中有一个顺序不同即视为不同顺序‘
    思路:当时以为可以取多个被坑了,然后一直以为是一个博弈,后来才看懂题,把四堆石子分为四个队伍,然后问所有队员排列有多少种方法,但是因为队伍内的人员有重复,所以要进行去重
    (a+b+c+d)!代表所有的数的全排列
    (a+b+c+d)/(a!*b!*c!*d!)(去重公式)
    (a+b+c+d)!代表所有的数的全排列

    由于第一队有a个元素,所以a个元素的全排是重复的。
    b,c,d同上。
    得出最后的结果
    (a+b+c+d)/(a!*b!*c!*d!)
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const ll N=2010,mo=1e9+7;
    ll power(ll a,ll b){//快速幂 
        ll ans=1;
        while (b){
            if (b&1)ans=ans*a%mo;
            a=a*a%mo;
            b>>=1;
        }return ans;
    }
    ll jc(ll a){
        ll ans=1;
        for (ll i=1;i<=a;i++)ans=ans*i%mo;
        return ans;
    }
    ll ny(ll x){//逆元 
        return power(x,mo-2);
    }
    ll a,b,c,d;
    int main(){
        cin>>a>>b>>c>>d;
        ll ans=jc(a+b+c+d);
        ans=ans*ny(jc(a))%mo*ny(jc(b))%mo*ny(jc(c))%mo*ny(jc(d))%mo;
        cout<<ans<<endl;
    }
  • 相关阅读:
    [BZOJ] 3191 [JLOI2013]卡牌游戏
    [LUOGU] P1466 集合 Subset Sums
    [LUOGU] P1113 杂物
    [BZOJ] 1003 [ZJOI2006]物流运输
    poj 2479 最大连续子段和
    C#学习第九弹之委托
    C#学习第八弹之线程基础理解
    C#学习第七弹之WPF
    hdu 2030 汉字的编码方式
    hdu 1559 暴力
  • 原文地址:https://www.cnblogs.com/Lis-/p/9094080.html
Copyright © 2011-2022 走看看