1. 程式人生 > >HDU 2200 Eddy's AC難題

HDU 2200 Eddy's AC難題

Eddy's AC難題

  Eddy是個ACMer,他不僅喜歡做ACM題,而且對於Ranklist中每個人的ac數量也有一定的研究,他在無聊時經常在紙上把Ranklist上每個人的ac題目的數量摘錄下來,然後從中選擇一部分人(或者全部)按照ac的數量分成兩組進行比較,他想使第一組中的最小ac數大於第二組中的最大ac數,但是這樣的情況會有很多,聰明的你知道這樣的情況有多少種嗎? 

  特別說明:為了問題的簡化,我們這裡假設摘錄下的人數為n人,而且每個人ac的數量不會相等,最後結果在64位整數範圍內. 

Input

  輸入包含多組資料,每組包含一個整數n,表示從Ranklist上摘錄的總人數。 
Output

  對於每個例項,輸出符合要求的總的方案數,每個輸出佔一行。 
Sample Input

2
4

Sample Output

1
17

解題思路:
  本題有多組測試,給出一個整數n為從Rank上摘錄的人數,將摘錄的人分為兩組,其中一組的所有人的AC數大於另一組,保證每個人的AC數都不一致。

  選出了n人,但是在分組時不一定將所有人都分組,所以我們m從2 ~ n選擇分組人數,選擇的種數可以用組合數計算得到,將選出的所有人按AC數量排序,若將一組個數為m有序數拆分為兩組,使其中一組的所有值大於另一組,可以在每兩個數中間進行拆分這樣便是求間隔的個數即為n-1。

排列組合相關運算

樣例分析:

2:

挑出2個數有2! / ((2 - 2)! * 2!) = 2 / (1 * 2) = 1

2個數分為兩組有1種情況,答案 = 1 * 1 = 1

4:

挑出2個數有 4! / ((4 - 2)! * 2!) = 6

2個數分為兩組有1種情況 挑出2個數時所有分組情況為6 * 1 = 6;

挑出3個數有 4! / ((4 - 3)! * 3! = 4

3個數分為兩組有3 - 1 = 2種情況 挑出3個數時所有分組情況為4 * 2 = 8

挑出4個數有 4! / ((4 - 4)! * 4!) = 1

4個數分為兩組有4 - 1 = 3種情況 挑出4個數時所有分組情況為1 * 3 = 3

答案 = 6 + 8 + 3 = 17

AC程式碼

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 LL clt(int n){
 5     LL ans = 0; //初始化答案為0
 6     for(int i = 2; i <= n; i++){    //從2個到n個挑出數字
 7         LL temp = 1;
 8         for(int j = 1; j <= i; j++){    //計算組合數
 9             temp = temp * (n - j + 1) / j;
10         }
11         ans += temp * (i - 1);  //計算答案
12     }
13     return ans;
14 }
15 int main()
16 {
17     int n;
18     while(scanf("%d", &n) != EOF){  //輸入摘錄人數
19         if(n < 2){ //人數小於2無法分為兩組輸出0
20             printf("0\n");  
21             continue;
22         }
23         LL ans = clt(n);    //人數大於2計算答案
24         printf("%lld\n", ans);
25     }
26     return 0;
27 }