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