BZOJ1002 FJOI2007 轮状病毒 递推

题意:给定一个轮状结构(中间一个点,周围有N个点以环状围住这个点),从不相交的2*N-1条边中选N条边,使任意两点间有且只有一条联通路径。
题解:请点这里。然而如果考场上考到直接打表找规律好了

#include 
#include 
#include 
#include 
#include 
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;
}
View Code

 

转载于:https://www.cnblogs.com/WDZRMPCBIT/p/6443516.html

你可能感兴趣的:(BZOJ1002 FJOI2007 轮状病毒 递推)