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 }