1. 程式人生 > >ACM~排列組合&&hdu樣例

ACM~排列組合&&hdu樣例

排列組合是數學中的一個分支,在計算機程式設計方面也有很多的應用,主要有排列公式和組合公式,錯排公式、母函式、Catalan Number(卡特蘭數)等。

一、有關組合數學的公式

1、排列公式   P(n,r)=n!/r!

2、組合公式   C(n,r)=n!/(r!*(n-r)!)  C(n,r)=C(n-1,r)+C(n-1,r-1)

3、錯排公式   d[1]=0;   d[2]=1;

                       d[n]=(n-1)*(d[n-1]+d[n-2])

4、卡特蘭數  

                       前幾項:1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786,208012…

                       公式       C(n)=C(2n,n)/(n+1)

5、母函式

數學中,某個序列的母函式是一種形式冪級數,其每一項的係數可以提供關於這個序列的資訊。使用母函式解決問題的方法稱為母函式方法 母函式可分為很多種,包括普通母函式指數母函式L級數貝爾級數狄利克雷級數。對每個序列都可以寫出以上每個型別的一個母函式。構造母函式的目的一般是為了解決某個特定的問題,因此選用何種母函式視乎序列本身的特性和問題的型別。(百度百科) 母函式模板(針對n的分解):
/******************************
題目大意:求分解整數n的個數q(n)
例:
5 = 5;
5 = 4 + 1;
5 = 3 + 1 + 1;
5 = 3 + 2;
5 = 2 + 2 + 1;
5 = 2 + 1 + 1 + 1;
5 = 1 + 1 + 1 + 1 + 1;
sum(5) = 7;不區分順序,
(3+2)與(2+3)為同一個
*******************************/
int main()
{
    int a[350],b[350],i,j,k,n;
    while(cin>>n&&n)
    {
        for(i=0;i<=n;i++){
            a[i]=1;
            b[i]=0;
        }
        for(i=2;i<=n;i++){
            for(j=0;j<=n;j++)
                for(k=0;k+j<=n;k+=i)
                    b[k+j]+=a[j];
            for
(
j=0;j<=n;j++){ a[j]=b[j]; b[j]=0; } } cout<<a[n]<<endl; } return 0; }

二、STL中的全排列函式

函式宣告:#include  <algorithm>

bool next_permutation( iterator start, iterator end);

next_permutation()函式功能是輸出所有比當前排列大的排列,順序是從小到大。

prev_permutation()函式功能是輸出所有比當前排列小的排列,順序是從大到小。

三、自己定義的全排列的函式

void range(int a[],int k,int n){
    if(k==n) {
        for(int i=1;i<=n;i++){
            printf("%d",a[i]);
        }
        printf("\n");
    }
    for(int i=k;i<=n;i++){
        swap(a[k],a[i]);
        range(a,k+1,n);
        swap(a[k],a[i]);
    }

}

四、hdu題目樣例