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

 题解:

    拿一张纸画一下,发现有这样一个关系式:f[i]=f[i-1]*3-f[i-2]+2。发现这样到第100项一定会爆long long,因此用高精度。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 struct node{
 9     int s[101];
10     int len;
11 }ans[110];
12 int n;
13 node mul(node a,int b){
14     int i,j;
15     for(i=1;i<=a.len;++i){
16         a.s[i]*=b;
17     }
18     for(i=1;i<=a.len;++i){
19         a.s[i+1]+=a.s[i]/10;
20         a.s[i]%=10;
21     }
22     if(a.s[a.len+1]!=0)  a.len++;
23     return a;
24 }
25 node miu(node a,node b){
26     int i,j=1;
27     a.s[1]+=2;
28     while(a.s[j]>=10){
29         a.s[j]%=10;a.s[++j]++;
30     }
31     for(i=1;i<=a.len;++i){
32         a.s[i]-=b.s[i];
33         if(a.s[i]<0){
34             a.s[i]+=10;a.s[i+1]--;
35         }
36     }
37     while(a.s[a.len]==0)  a.len--;
38     return a;
39 }
40 int main(){
41     scanf("%d",&n);
42     ans[1].s[1]=1;ans[0].s[1]=0;
43     ans[1].len=ans[0].len=1;
44     int i,j;
45     for(i=2;i<=n;++i){
46         ans[i]=miu(mul(ans[i-1],3),ans[i-2]);
47     }
48     for(i=ans[n].len;i>=1;--i){
49         printf("%d",ans[n].s[i]);
50     }
51     return 0;
52 }
bzoj1002

 

posted @ 2018-02-25 17:43  lazytear  阅读(68)  评论(0编辑  收藏