BZOJ1005 [HNOI2008]明明的烦恼

用到的一个东西叫做树的prufer编码,百度百科的就挺好,很好懂

然后就是组合数了,分成确定度和自由度两类进行计算,具体不说了。

需要特判无解的情况,大概就是n为1的时候,度不为0。或者n>1的时候度有小于1的或者确定的度大于n-2。

需要高精度,偷懒直接用JAVA写了。

 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 }

 

posted on 2015-08-15 14:22  round_0  阅读(199)  评论(0编辑  收藏  举报

导航