排列組合的去重問題


題目描述

給出四堆石子,石子數分別為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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM