【bzoj1002】[FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4381  Solved: 2393
[Submit][Status][Discuss]

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  (我也不会证)
关于基尔多夫矩阵,传送门:http://www.cnblogs.com/chty/p/5868327.html
当然,得用到高精度。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 using namespace std;
 9 struct bignum{int len,num[1010];}f[110],p;
10 int n;
11 bignum add(bignum a,bignum b)
12 {
13     int len;  bignum c;
14     memset(c.num,0,sizeof(c.num));
15     if(a.len>=b.len) len=a.len;
16     else len=b.len;
17     for(int i=1;i<=len;i++)
18     {
19         c.num[i]+=a.num[i]+b.num[i];
20         if(c.num[i]>=10) 
21         {
22             c.num[i+1]+=1;
23             c.num[i]-=10;
24         }
25     }
26     if(c.num[len]>0)
27         len++;
28     c.len=len;
29     return c;
30 }
31 bignum Mull(bignum a,int b)
32 {
33     int i,len;  bignum c;
34     len=a.len;
35     memset(c.num,0,sizeof(c.num));
36     for(i=1;i<=len;i++)
37     {
38         c.num[i]+=(a.num[i]*b);
39         if(c.num[i]>=10)
40         {
41             c.num[i+1]=c.num[i]/10;
42             c.num[i]=c.num[i]%10;
43         }
44     } 
45     len=len+1;
46     while(c.num[len]>0)
47     {
48         c.num[len+1]=c.num[len]/10;
49         c.num[len++]%=10;
50     }    
51     c.len=--len;
52     return c;
53 }
54 bignum sub(bignum a1,bignum b1)
55 {
56     int len;
57     if(a1.len>b1.len)  len=a1.len;
58     else  len=b1.len;
59     for(int i=1;i<=len;i++)
60     {
61         a1.num[i]=a1.num[i]-b1.num[i];
62         if(a1.num[i]<0)
63         {
64             a1.num[i]+=10;
65             a1.num[i+1]--;
66         }
67         
68     }
69     while(a1.num[len]==0&&len>1)  len--;
70     a1.len=len;
71     return a1;
72 }
73 
74 void print(bignum c)
75 {
76     for(int i=c.len;i>0;i--)
77         printf("%d",c.num[i]);
78     printf("\n");
79 }
80 int main()
81 {
82     scanf("%d",&n);
83     f[1].len=f[2].len=p.len=1;
84     f[1].num[1]=1;  f[2].num[1]=5;  p.num[1]=2;
85     for(int i=3;i<=n;i++)
86         f[i]=sub(add(Mull(f[i-1],3),p),f[i-2]);
87     print(f[n]);
88     return 0;
89 }
View Code

 

posted @ 2016-09-06 17:54  chty  阅读(753)  评论(0编辑  收藏  举报