BZOJ_1002_[FJOI2007]_轮状病毒_(递推+高精)

描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1002

)*&*(^&*^&*^**()*)

 

 

1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4060  Solved: 2239
[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

 

HINT

 

Source

 

 

分析


题目是求一种特殊的图的生成树的个数,但是貌似有更一般的算法,等明天再看吧...

只搞懂了打表找规律,然后题推的解法.

随便写个暴力打个表(其实我并不会写,明天再写吧今天好累),找一找规律.

1~14的答案如下

 

1 5 16 45 121 320 841 2205 5776 15125 39601 103680 271441 710645
奇数项
1 16 121 841 5776 39601 271441
开根号得
1 4 11 29 76 199 521
a[i]=a[i-1]*3-a[i-2]
偶数项
5 45 320 2205 15125 103680 710645
除以5得
1 9 64 441 3025 20736 142129
开根号得
1 3 8 21 55 144 377
a[i]=a[i-1]*3-a[i-2]

 

注意要用高精(学习了别人的高精写法,自己写得太小学生了)

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 struct Big_Integer{
 6     int x[100],cnt;
 7     int & operator [] (int id){
 8         return x[id];
 9     }
10     void operator = (int y){
11         x[1]=y;
12         cnt=1;
13     }
14 }f[100];
15 Big_Integer operator - (Big_Integer x,Big_Integer y){
16     Big_Integer z=f[0];
17     z.cnt=max(x.cnt,y.cnt);
18     for(int i=1;i<=z.cnt;i++){
19         z[i]+=x[i]-y[i];
20         if(z[i]<0) z[i+1]--, z[i]+=10;
21     }
22     while(z.cnt&&!z[z.cnt]) z.cnt--;
23     return z;
24 }
25 Big_Integer operator * (Big_Integer x,Big_Integer y){
26     Big_Integer z=f[0];
27     for(int i=1;i<=x.cnt;i++){
28         for(int j=1;j<=y.cnt;j++){
29             z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/10,z[i+j-1]%=10;
30         }
31     }
32     z.cnt=x.cnt+y.cnt;
33     if(!z[z.cnt]) z.cnt--;
34     return z;
35 }
36 Big_Integer operator * (Big_Integer x,int y){
37     Big_Integer z=f[0];
38     for(int i=1;i<=x.cnt;i++){
39         z[i]+=x[i]*y,z[i+1]+=z[i]/10,z[i]%=10;
40     }
41     z.cnt=x.cnt;
42     if(z[z.cnt+1]) z.cnt++;
43     return z;
44 }
45 ostream& operator << (ostream &out,Big_Integer x){
46     for(int i=x.cnt;i;i--){
47         out << x[i];
48     }
49     return out;
50 }
51 int n;
52 int main(){
53     cin >> n;
54     f[1]=1;
55     f[2]=n&1?4:3;
56     int last=n+1>>1;
57     for(int i=3;i<=last;i++){
58         f[i]=f[i-1]*3-f[i-2];
59     }
60     cout << f[last]*f[last]*(n&1?1:5) << endl;
61     return 0;
62 }
View Code

 

 

posted @ 2016-05-13 23:30  晴歌。  阅读(246)  评论(0编辑  收藏  举报