1. 程式人生 > >容斥原理的幾個問題總結

容斥原理的幾個問題總結

據文章說,原文是俄文的,各種翻譯才成為中文。表示膜拜,仰慕。ORZ。就需要這麼屌屌噠人。。

容斥原理的具體證明就不在描述了。。

 

這應該是對容斥原理最簡單粗暴的解釋了。。

我們這篇文章關鍵解釋了幾個有關容斥原理的小小問題。

1.一個簡單的排列問題。

由0到9的數字組成排列,要求第一個數大於1,最後一個小於8,問,共有多少種排列?

分析:直接求的話,求起來很複雜。那麼我們可以求該排列的逆問題。也就是求第一數<=1,或者最後一位數>=8的排列數。

我們假設A為第一個數<=1,B為最後一個數>=8。

那麼我們要求的逆問題的排列數就是A + B - (A & B)。(我們定義‘+’為集合的並,&為集合的交集,數學符號和邏輯符號並用,望諒解)。。

為什麼藥減去A & B呢?因為我們的A,也就是說第一個數<=1中也有滿足最後一個數>=8的情況,同樣的最後一個數>=8的情況中也有第一個數<=1的,那麼我們A+B就會多加一部分第一個數<=1&&最後一個數>=8,減去的就是這一部分。。

C = A + B - (A & B) = 2 * 9! + 2 * 9! - 2 * 2 * 8!。那麼這部分就是第一位<=1,或者最後一個>=8的排列數。。

我們用10! - C就是我們要求的,第一個數大於1,最後一個數小於8的排列數。。

2.(0, 1, 2)序列問題。

長度為n,由0,2,1組成序列,每個數最少出現一次,這樣的序列有多少種。

分析:我們發現,直接求解的話也是比較複雜的。。那麼我們就可以求解他是逆問題。

也就是不全部出現0,1,2的序列會有多少種。。用原文是話就是,不出現某些數的序列的種數。

我們設A0是不出現0的序列的個數,A1是不出現1的序列的個數,A2是不出現2的序列的個數。

A0 + A1 + A2 - (A0 & A1) - (A0 & A2) - (A1 & A2) + (A0 & A1 & A2)。就是我們所要求的逆問題是序列。看下面的維恩圖:

畫的有點挫(不是有點,是太挫了。。。。 - -)。。

可以看來我們可以用另一個問題來解釋了。。這個問題是維恩圖與求同時不能被三個數整除的一樣了。。其實差不多。。

C = A0 + A1 + A2 - (A0 & A1) - (A0 & A2) - (A1 & A2) + (A0 & A1 & A2) = 2^n + 2^n + 2^n - 1 - 1 - 1 + 0.。這就是序列中不出現某些數序列的種類數。。。

總共是序列眾數 3^n - (3 * 2^n - 3 + 0)。。就是我們所求的每個數都最少出現一次的序列數。。

3.方程整數解問題。

給一個方程 x1 + x2 + x3 + x4 + x5 + x6 = 20, 0 <= xi <= 8。。問這樣的整數解有多少種。。

4.求指定區間內與n互素的數有多少個。。

給定r,n 求[1,r]內與n互素的個數有多少個?看到這個問題,數論有學一點的童鞋可能會想如果r = n的話,不就是尤拉函數了嗎?是的,可惜這個問題的r ,n是不一定會相等的。。

分析:直接求解問題就是比較複雜的。所以我們還是研究這個問題是逆問題。也就是說求gcd(k,n) >= 2,在1 -  n 之間k有多少個 。

那麼我們就可以列舉n的素因子來進行求解。。。

Code:小小程式碼:

//時間複雜度O(sqrt(n))...
int solve(int r, int n)
{
    int p[N], top = 0, ans;
    for(int i = 2; i * i <= n; i ++){
        if(n % i == 0){
            p[top ++] = i;
            while(n % i == 0) n = n / i;
        }
    }
    if(n > 1) p[top ++] = n;
    //列舉子集來進行判斷加減,cnt為子集元素個數
    for(int i = 1; i < (i << top); i ++){
        int cnt = 0, tmp = 1;
        for(int j = 0; j < top; j ++){
            cnt ++;
            tmp = tmp * p[j];
        }
    }
    if(cnt % 2) ans += r / tmp;
    else ans -= r / tmp;
    return r - ans;
}

這個問題還是比較有趣的。。。

5.在給定區間內被給定集合中至少一個數整除的個數。。

6.能滿足一定數目匹配的字串個數問題。

7.路徑數目問題。

8.素數四元組問題。

給你n個數