算法競賽訓練指南2.1 計數方法
阿新 • • 發佈:2018-09-11
而且 -s 問題 排列 while syn cin 講解 sig
1. O(n)方法求C(n,m)
利用公式C(n,k+1)=C(n,k)*(n-k)/(k+1)
模板:
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long LL;
const int maxn=100005;
LL n,m;
LL C()
{
if(m==0||n==m)
return 1;
if(m>n-m)
m=n-m;
LL ans,temp=1;
for(LL i=1 ;i<=m;i++)
{
ans=temp*(n-i+1)/i;
temp=ans;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
cout<<C()<<endl;
}
return 0;
}
2. 有重復元素的全排列,有k個元素,其中第i個元素有ni個,求全排列的個數
見白書的細致講解,書上面說的更清楚。
3. 可重復的選取的組合,有n個不同的元素,每個元素可以選多次,一共選k個元素,有多少種方法。
想法:設第i個元素選xi個,問題就轉化為了x1+x2+x3+...+xn=k的非負整數解有多少個,就相當於把k個元素分為n組,那麽只需要再這些元素中插入n-1個板,然後再n-1+k當中找這n-1塊板,那麽結果就是C(n+k-1,n-1)=C(n-1+k,k);
4. 單色三角形:給定n個點,且沒有三色共線,每兩個點之間都用黑色或者紅色的線段連接,求3條邊同色的三角形數。
想法:求同色的可以先求不同色的,每個非單色的三角形中,恰好有兩個頂點連接兩條異色邊,而且有一個公共點的兩條異色邊總是唯一對應一個非單色三角形,因此如果第i個點連接了ai條紅邊,n-1-ai條黑邊,則這些邊屬於ai*(n-1-ai)個非單色的三角形,每個非單色的三角形選了兩次故還需要除以2,這樣同色的也就求出來了。
算法競賽訓練指南2.1 計數方法