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;
    }
  • 相关阅读:
    Linux常用命令大全
    Activity的launchMode详细分析
    StringBuilder与StringBuffer的区别(转)
    CSS那些事儿-阅读随笔3(清除浮动)
    CSS那些事儿-阅读随笔2(选择符的组合与优先级/权重)
    CSS那些事儿-阅读随笔1(CSS简介与选择符)
    js快速打印一个五分制(五颗星)的评分情况
    jQgrid问题总结
    Webstorm10.0.4注册码
    浅谈Websocket、Ajax轮询和长连接(long pull)
  • 原文地址:https://www.cnblogs.com/kugwzk/p/5076135.html
Copyright © 2011-2022 走看看