1. 程式人生 > >算法競賽訓練指南2.1 計數方法

算法競賽訓練指南2.1 計數方法

而且 -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 計數方法