BZOJ [FJOI2007]轮状病毒

分析:

我其实想到链状怎么做了,没有往下多想。一直想用组合做。

最后看到CLJ的题解,才发现我已经想对了一半。。。

 

对于一个链来说,设Dp[i]为长度为i的链和一个“中心”的生成树数量,可以Dp之。。
然后考虑环,枚举1节点所在的环的长度,设为Len,那么这个环的位置有Len种情况,这个环与中心连接也有Len种情况,那么这个节点对答案的贡献就是Len^2*Dp[n-Len]。。

转自:http://hi.baidu.com/wjbzbmr/item/3f5e90f02b913ed66225d201

 

View Code
 1 #include <cstring>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <iostream>
 6 
 7 #define N 50
 8 
 9 using namespace std;
10 
11 struct BIGN
12 {
13     int a[N];
14 }dp[110],ans;
15 
16 int n;
17 
18 inline BIGN operator +(BIGN a,BIGN b)
19 {
20     BIGN c; memset(c.a,0,sizeof c.a);
21     c.a[0]=max(a.a[0],b.a[0]);
22     int jin=0;
23     for(int i=1;i<=c.a[0];i++)
24     {
25         jin+=a.a[i]+b.a[i];
26         c.a[i]=jin%10000;
27         jin/=10000;
28     }
29     while(jin) c.a[++c.a[0]]=jin%10000,jin/=10000;
30     return c;
31 }
32 
33 inline BIGN operator *(BIGN a,int b)
34 {
35     BIGN c; memset(c.a,0,sizeof c.a);
36     int jin=0;
37     for(int i=1;i<=a.a[0];i++)
38     {
39         jin+=c.a[i]+a.a[i]*b;
40         c.a[i]=jin%10000;
41         jin/=10000;
42     }
43     c.a[0]=a.a[0];
44     while(jin) c.a[++c.a[0]]=jin%10000,jin/=10000;
45     return c;
46 }
47 
48 void prev()
49 {
50     dp[0].a[0]=dp[0].a[1]=1;
51     dp[1].a[1]=dp[1].a[0]=1;
52     for(int i=2;i<=100;i++)
53     {
54         dp[i].a[1]=0;dp[i].a[0]=1;
55         for(int j=1;j<=i;j++)
56             dp[i]=dp[i]+dp[i-j]*j;
57     }
58     
59 }
60 
61 void prt(const BIGN &a)
62 {
63     printf("%d",a.a[a.a[0]]);
64     for(int i=a.a[0]-1;i>=1;i--) printf("%.4d",a.a[i]);
65     puts("");
66 }
67 
68 int main()
69 {
70     prev();
71     scanf("%d",&n);
72     ans.a[1]=0; ans.a[0]=1;
73     for(int i=1;i<=n;i++)
74         ans=ans+dp[n-i]*(i*i);
75     prt(ans);
76     return 0;
77 }

 

posted @ 2012-10-28 21:06  proverbs  阅读(906)  评论(0编辑  收藏  举报