• 全错位排列


    全错位排列是由著名数学家欧拉提出的。

    最典型的问题是装错信封问题

    一个人写了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

    神,上帝和老天爷

  • 相关阅读:
    Shell 数组
    Shell 中的中括号用法总结
    设置Linux可以查看历史命令(history)的执行时间
    jasypt 对 配置文件密码进行加密处理
    今日进度
    今日进度
    今日进度
    今日进度
    今日进度
    每周总结
  • 原文地址:https://www.cnblogs.com/magicsoar/p/4196742.html
Copyright © 2020-2023  润新知