[Bzoj]1002: [FJOI2007]轮状病毒
Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
基尔霍夫矩阵:F[i]=(F[i-1]*3-F[i-2]+2)
高精度是必须的
1 #include<iostream> 2 #include<cstring> 3 #include<iomanip> 4 using namespace std; 5 6 const int MAXN=100000; 7 const int WIDE=10000; 8 9 int n; 10 int F[101][MAXN]={0},L[101]; 11 12 void Mult(int *A,int *B,int &LA,int &LB,int n) 13 { 14 memset(B,0,sizeof(int)*MAXN);LB=LA+1; 15 for(int i=0;i<LA;i++) 16 { 17 B[i]+=A[i]*n; 18 if(B[i]>=WIDE) 19 { 20 B[i+1]+=B[i]/WIDE; 21 B[i]%=WIDE; 22 } 23 } 24 if(B[LB]>0) LB++; 25 } 26 27 void Dec(int *A,int *B,int &LA,int &LB) 28 { 29 int T[MAXN]; 30 int L=max(LA,LB); 31 memset(T,0,sizeof(T)); 32 for(int i=0;i<L;i++) 33 { 34 T[i]+=A[i]-B[i]; 35 if(T[i]<0) 36 T[i]+=WIDE,T[i+1]--; 37 } 38 while(T[L-1]==0) L--; 39 for(int i=0;i<L;i++) 40 A[i]=T[i]; 41 LA=L; 42 } 43 44 void Add(int *A,int &L,int n) 45 { 46 A[0]+=n; 47 A[L]=0;//不知道为什么A[L]会等于1,害我调试好久 48 for(int i=0;i<L;i++) 49 { 50 if(A[i]>=WIDE) 51 A[i]-=WIDE,A[i+1]++; 52 } 53 if(A[L]>0) L++; 54 } 55 56 int main() 57 { 58 cin>>n; 59 F[1][0]=1;F[2][0]=5; 60 for(int i=1;i<=n;i++) L[i]=1; 61 for(int i=3;i<=n;i++) 62 { 63 Mult(F[i-1],F[i],L[i-1],L[i],3); 64 Dec(F[i],F[i-2],L[i],L[i-2]); 65 Add(F[i],L[i],2); 66 } 67 cout<<F[n][L[n]-1]; 68 for(int i=L[n]-2;i>=0;i--) 69 { 70 cout.width(4); 71 cout.fill('0'); 72 cout<<F[n][i]; 73 } 74 return 0; 75 }