BZOJ1002 FJOI2007 轮状病毒 递推
题意:给定一个轮状结构(中间一个点,周围有N个点以环状围住这个点),从不相交的2*N-1条边中选N条边,使任意两点间有且只有一条联通路径。
题解:请点这里。然而如果考场上考到直接打表找规律好了
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int BASE=1000; const int MAXN=100+2; const int MAXL=100+2; struct Bignum{ int Len,Num[MAXL]; void Output(){ for(int i=Len,j=BASE/10;i;i--,j=BASE/10){ while(i!=Len && j>Num[i]) cout << 0,j/=10; if(Num[i]) cout << Num[i]; } cout << endl; } Bignum operator=(Bignum a){ Len=a.Len; memcpy(Num,a.Num,sizeof(Num)); } Bignum operator*(int x){ int Carry=0; Bignum Ans; memset(Ans.Num,0,sizeof(Ans)),Ans.Len=Len; for(int i=1;i<=Len;i++){ Ans.Num[i]=x*Num[i]+Carry; Carry=Ans.Num[i]/BASE,Ans.Num[i]%=BASE; } while(Carry) Ans.Num[++Ans.Len]=Carry%BASE,Carry/=BASE; return Ans; } Bignum operator+(int x){ Bignum Ans; memcpy(Ans.Num,Num,sizeof(Num)); Ans.Len=Len,Ans.Num[1]+=x; for(int i=1;Ans.Num[i]>=BASE && i<=Len;i++) Ans.Num[i+1]+=Ans.Num[i]/BASE,Ans.Num[i]%=BASE; if(Ans.Num[Ans.Len]>=BASE) Ans.Len++,Ans.Num[Len+1]=Ans.Num[Len]/BASE,Ans.Num[Len]%=BASE; return Ans; } Bignum operator-(Bignum a){ bool Borrow=0; Bignum tmp; memset(tmp.Num,0,sizeof(tmp.Num)); tmp.Len=max(a.Len,Len); for(int i=1;i<=tmp.Len;i++){ tmp.Num[i]=Num[i]-a.Num[i]-Borrow; if(tmp.Num[i]<0) Borrow=1,tmp.Num[i]+=BASE; else Borrow=0; } while(!tmp.Num[tmp.Len]) tmp.Len--; return tmp; } }f[MAXN]; int N; int main(){ cin >> N; memset(f,0,sizeof(f)); f[1].Len=1,f[1].Num[1]=1; f[2].Len=1,f[2].Num[1]=5; for(int i=3;i<=N;i++) f[i]=f[i-1]*3-f[i-2]+2; f[N].Output(); return 0; }