zoukankan      html  css  js  c++  java
  • [hdu-2048] 神、上帝以及老天爷

    神、上帝以及老天爷

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 20794    Accepted Submission(s): 8780


    Problem Description
    HDU 2006'10 ACM contest的颁奖晚会隆重開始了!
    为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的详细要求是这种:

    首先,全部參加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
    然后,待全部字条增加完成,每人从箱中取一个字条;
    最后,假设取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”

    大家能够想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!只是,正如全部试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后居然没有一个人中奖!

    我的神、上帝以及老天爷呀,怎么会这样呢?

    只是,先不要激动,如今问题来了,你能计算一下发生这样的情况的概率吗?

    不会算?难道你也想以悲剧结尾?!
     

    Input
    输入数据的第一行是一个整数C,表示測试实例的个数,然后是C 行数据,每行包括一个整数n(1<n<=20),表示參加抽奖的人数。

     

    Output
    对于每一个測试实例,请输出发生这样的情况的百分比,每一个实例的输出占一行, 结果保留两位小数(四舍五入),详细格式请參照sample output。

     

    Sample Input
    1 2
     

    Sample Output
    50.00%
     

    分析:这是一道递推题

    1、n 个人 n 张票,就有 n! 种排列情况。我们须要做的就是从这 n! 种情况中,找出 n 个人全部的错排情况。

    2、如果有 n 个人,错排情况数是 f ( n ) ,把他们分成 1 个人和 n - 1 个人两部分。有例如以下 3、4 两种情况:

    3、如果 1 个人拿的是自己的票, n - 1 拿的都不是自己的票,那么这 1 个人仅仅须要和这 n - 1 个人中不论什么一个人交换一下票,就可满足 n 个人错排。所以有 ( n - 1 ) * f ( n - 1 ) 。

    4、如果 n - 1 个人其中有一个人拿的是自己的票,1 个人拿的无论是不是自己的票,仅仅要和 n - 1 个人其中那个拿自己票的人交换一下,就可满足 n 个人错排。并且,n - 1 个人其中除掉拿自己票的人,n - 2 个人肯定满足错排。所以又有 ( n - 1 ) * f ( n - 2 ) 。

    综上所述:f ( n ) = ( n - 1) * [ f ( n - 1 ) + f ( n - 2 ) ]

    敲代码时,能够利用一个二维数组cases [ 21 ] [ 2 ] ,数组第 0 列存储 n 个人的全部排列情况 n! ,数组第 1 列存储 n 个人的错排情况 f ( n ) = ( n - 1) * [ f ( n - 1 ) + f ( n - 2 ) ]

    import java.util.Scanner;
    
    public class Main {
    
    	static long[][] cases = new long[21][2];
    
    	static {
    		cases[1][0] = 1;
    		cases[1][1] = 0;
    		cases[2][0] = 2;
    		cases[2][1] = 1;
    
    		for (int i = 3; i < 21; i++) {
    			cases[i][0] = i * cases[i - 1][0];
    			cases[i][1] = (i - 1) * (cases[i - 1][1] + cases[i - 2][1]);
    		}
    	}
    
    	public static void main(String[] args) {
    		Scanner scanner = new Scanner(System.in);
    		int n = scanner.nextInt();
    
    		while (n-- != 0) {
    			int count = scanner.nextInt();
    
    			System.out.printf("%.2f", 100.0 * cases[count][1] / cases[count][0]);
    			System.out.println("%");
    		}
    	}
    }

  • 相关阅读:
    poj 3280 Cheapest Palindrome(区间DP)
    POJ 2392 Space Elevator(多重背包)
    HDU 1285 定比赛名次(拓扑排序)
    HDU 2680 Choose the best route(最短路)
    hdu 2899 Strange fuction (三分)
    HDU 4540 威威猫系列故事――打地鼠(DP)
    HDU 3485 Count 101(递推)
    POJ 1315 Don't Get Rooked(dfs)
    脱离eclipse,手动写一个servlet
    解析xml,几种方式
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4006170.html
Copyright © 2011-2022 走看看