zoukankan      html  css  js  c++  java
  • 2015年秋校赛第4题

    4.Broken array

    Description

    There are n (n < = 10000) different books on n different shelves. Books number from 1 to n, so do shelves. Every shelf has one book. Originally, the book i on the shelf i. Now, let’s rearrange the books. The request is to make every book not be in the original position. For example, there are 4 books and the original permutation is 1,2,3,4 . When we rearrange, the permutation 2,3,4,1 is legal, but the permutation 1,3,4,2 is illegal. We want to know how many different legal permutations exist (The answer needs to modulo 1000000007)?

    Input

    The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. Then T(0<T <= 100) tests cases follow. Next T line, every line contains a integer n(1<=n<=10000),which denotes the number of books.

    Output

    Print a integer m for every case, and m denotes the number of legal permutations.

    Sample Input

    4
    1
    3
    5
    10

    Sample Output

    0
    2
    44
    1334961
     
    分析:其实这是一个全错排的问题,也是欧拉提出的信封问题。解决这个问题其实可以用递归的想法:我们记对于n个元素全错排的种数一共有M(n)种方法。对于n个元素,如果一开始从第n个开始排,因为要求全错排,那么它只有n-1中放法。我们假设它放到了k这个位置。那么对于原先放在k这个位置的元素k来说,它现在有两种选择:(1)如果放到n的位置上,那么接下来的问题就是剩下的n-2个元素的全错排。那么共有M(n-2)种方法。(2)如果k并没有放到n这个位置上,那么其实就是(n-1)个元素进行全错排,那么有M(n-1)种方法。那么M(n)=(n-1)*[M(n-1)+M(n-2)].
      其实这时候我们已经找到解决问题的方法了,但因为数据过大,所以我们减少程序的运行时间还得进行进一步的优化。所以可以用数组来储存每一次的结果,那么当下一次递归到这种情况的时候,就可以直接返回答案,而不需要计算。
    代码如下:
    #include <stdio.h>
    long long score[10005]={0};
    long long erratum(int n)
    {
        if(score[n]!=0)
            return score[n];
        else{
            if(n==1)
                score[n]=0;
            else if(n==2)
                score[n]=1;
            else{
                score[n]=((n-1)*(erratum(n-1)%1000000007+erratum(n-2)%1000000007))%1000000007;
            }
        }
        return score[n];
    }
    int main()
    {
        int T,n;
        long long ret;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            ret=erratum(n);
            printf("%I64d
    ",ret);
        }
        return 0;
    }
  • 相关阅读:
    time 类
    案例:手动输入一个字符串,所有字符反转,大小写相互转
    案例:使用列表年月日 计算这个日期是这一天的多少天
    用python输出1-100之间所有的质数
    案例:手动输入一个字符串,打散放进一个列表,小写字母反序 大写字母保持不变
    安装数据库教程
    PHP use MySQLi
    PHP logging
    Vagrant
    Flask基础
  • 原文地址:https://www.cnblogs.com/kugwzk/p/5076135.html
Copyright © 2011-2022 走看看