BZOJ1005 [HNOI2008]明明的煩惱

用到的一個東西叫作樹的prufer編碼,百度百科的就挺好,很好懂java

而後就是組合數了,分紅肯定度和自由度兩類進行計算,具體不說了。ide

須要特判無解的狀況,大概就是n爲1的時候,度不爲0。或者n>1的時候度有小於1的或者肯定的度大於n-2。編碼

須要高精度,偷懶直接用JAVA寫了。spa

 1 import java.io.*;
 2 import java.math.*;
 3 import java.util.*;
 4 public class Main
 5 {
 6     public static void main(String[] args){
 7         Scanner cin = new Scanner(new BufferedInputStream(System.in));
 8         int a[] = new int[1005];
 9         int n = cin.nextInt(),s = 0;
10         for(int i = 1;i<=n;++i)a[i] = cin.nextInt();
11         if(n==1){
12             if(a[1]==0||a[1]==-1)System.out.println(1);
13             else System.out.println(0);
14             return;
15         }
16         int m = 0;
17         for(int i = 1;i<=n;++i)if(a[i]!=-1){
18             if(a[i]<1){System.out.println(0);return;}
19             a[i]--;s+=a[i];m++;
20         }
21         if(s>n-2){System.out.println(0);return;}
22         BigInteger f[] = new BigInteger[1005];
23         f[1] = BigInteger.ONE;f[0] = f[1];
24         for(int i = 2;i<=n;++i)
25             f[i] = f[i-1].multiply(BigInteger.valueOf(i));
26         BigInteger ans = f[n-2].divide(f[n-2-s]);
27         BigInteger x = BigInteger.valueOf(n-m);
28         for(int i = 1;i<=n;++i)if(a[i]!=-1)
29             ans = ans.divide(f[a[i]]);  ///已經不少次寫成 ans.divide(f[a[i]]);總是忘記賦值
30         for(int i = 1;i<=n-s-2;++i)ans = ans.multiply(x);
31         System.out.println(ans);
32     }
33 }
相關文章
相關標籤/搜索