全錯位排列


全錯位排列是由著名數學家歐拉提出的。

最典型的問題是裝錯信封問題

一個人寫了n封不同的信及相應的n個不同的信封,他把這n封信都裝錯了信封,問都裝錯信封的裝法有多少種?

用a、b、c,d……表示n份相應的寫好的信紙,A、B、C,D……表示寫着n位友人名字的信封,錯裝的總數為記作f(n)。

假設把a錯裝進B中,然后接下來我們可以分為兩種情況,

第一種是b錯裝進了A中,那么問題就變為c,d,e…..n-2個信紙放入C,D,E……n-2個信封時完全放錯時完全裝錯有多少種,有f(n-2)種

第二種是b錯裝進了除A之外的一個信封內,這個時候問題就相當於已知a錯裝進B中,將b,c,d,e…..n-2個信紙放入A,C,D,E……n-2個信封時,b不能放入A中,這里如果我們把A

想象成B0的話,就相當於將b,c,d,e…..n-2個信紙放入B0,C,D,E……n-2個信封時完全放錯,有f(n-1)種

a錯裝進B中,有f(n-1)+f(n-2)種,同樣a錯裝進C中也有f(n-1)+f(n-2)種…..

a錯裝進B中,有f(n-1)+f(n-2)種

a錯裝進C中,有f(n-1)+f(n-2)種

a錯裝進D中,有f(n-1)+f(n-2)種

a錯裝進E中,有f(n-1)+f(n-2)種

a錯裝進F中,有f(n-1)+f(n-2)種

所以一共有

f(n)=(n-1)(f(n-1)+f(n-2));

 

//C++示例代碼
#include <iostream>
using namespace std;

long long getvalue(int num)
{
    if (num == 1)
    {
        return 0;
    }
    else if (num == 2)
    {
        return 1;
    }
    else if (num == 3)
    {
        return 2;
    }
    else
    {
        long long f1 = 1;
        long long f2 = 2;
        for (int i = 4; i <= num; i++)
        {
            long long t = f2;
            f2 = (i - 1)*(f1 + f2);
            f1 = t;
        }
        return f2;
    }
}

int main()
{
    int num;
    cout << "input the number of envelop with -1 to end" << endl;
    while (cin>>num)
    {
        if (num == -1)
            break;
        long long r = getvalue(num);
        cout<<"Result:" << r << endl;
    }
    return 0;
}

 

相關的題目有

http://acm.hdu.edu.cn/showproblem.php?pid=2049

假設一共有N對新婚夫婦,其中有M個新郎找錯了新娘,求發生這種情況一共有多少種可能.

 

http://acm.hdu.edu.cn/showproblem.php?pid=2048

神,上帝和老天爺


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM