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 }
弱者究竟为何而战?!