[bzoj1002][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

Solution

#include<stdio.h>
#include<string.h>
struct big{
    int x[110],ln;
}f[110];
big sub(big a,big b){
    big c=a;
    c.x[1]+=2;
    for(int i=1;i<=c.ln;i++){
        c.x[i]-=b.x[i];
        if(c.x[i]<0)
            c.x[i]+=10,
            c.x[i+1]--;
    }
    while(!c.x[c.ln])c.ln--;
    return c;
}
big mul(big a){
    big c=a;
    for(int i=1;i<=c.ln;i++)
        c.x[i]*=3;
    for(int i=1;i<=c.ln;i++)
        c.x[i+1]+=c.x[i]/10,
        c.x[i]%=10;
    while(c.x[c.ln+1])c.ln++;
    return c;
}
int n;
int main(){
    scanf("%d",&n);
    f[1].x[1]=f[1].ln=1;
    f[2].x[1]=5;f[2].ln=1;
    for(int i=3;i<=n;i++)
        f[i]=sub(mul(f[i-1]),f[i-2]);
    for(int i=f[n].ln;i;i--)
        printf("%d",f[n].x[i]);
    putchar('\n');
    return 0;
}

 

posted @ 2017-01-09 21:53  keshuqi  阅读(227)  评论(0编辑  收藏  举报