洛谷2144 [FJOI2007]轮状病毒

题目描述
轮状病毒有很多变种。许多轮状病毒都是由一个轮状基产生。一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成。2个原子之间的边表示这2个原子之间的信息通道,如图1。

n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有16个不同的3轮状病毒,入图2所示。

给定n(N<=100),编程计算有多少个不同的n轮状病毒。

输入输出格式
输入格式:
第一行有1个正整数n。

输出格式:
将编程计算出的不同的n轮状病毒数输出

输入输出样例
输入样例#1:
3
输出样例#1:
16

题意:

中间一个点,周围围着n个点,求生成树的个数。周围n个点是不相同的,即一个图旋转一下得到的图和原图只要长得不一样就可以多算一个。

思路:

据说可以用矩阵树定理做,但是要用到行列式这样听都没听说过的东西,当然放弃了。
然后想用DP做,自己想了很久推不出来,于是看了题解(所以自己是不可能想出来的呀

题解思路 f [ i ] 表示除了第1个外围点和第i个外围点相连的情况之外,其他所有情况数,相应的 g [ i ] 表示第1个外围点和第i个外围点相连的情况数。

首先看 f [ i ] 的求法: f [ i ] = j = 1 j i f [ i j ] j 这个公式表示,在 f [ i j ] 的基础上,加入后j个点,这j个点里,需要选一个点与中间点相连,其他点负责把这j个点连成一片。这个公式明显是对的,然而一晚上都没有想到。

然后看 g [ i ] 的求法: g [ i ] = j = 2 j i f [ i j ] j ( j 1 ) 这个公式表示,首先从i个点里面取出j个点,让这j个点连成一条,并且这j个点包含第个1点和第个i点,这样的取法有(j-1)种,然后这j个点里连向中间点的方案数有j种,而剩下的i-j个点方案数即f[i-j]。

于是最后的答案就是f[n]+g[n]。

然后为了复杂度不爆炸(虽然n = 100还是可以水过的),加上多阶差分,乱搞搞,复杂度就少了一个n。

最后贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 110;
const int L = 1010;
int n;
struct NUM{
    int len, s[L];
    NUM operator = (int x){
        memset(s, 0, sizeof(s));
        len = 1;
        s[1] = x;
        return *this;
    }
    NUM operator + (NUM x){
        NUM y;
        memset(y.s, 0, sizeof(y.s));
        y.len = max(len, x.len);
        for (int i = 1; i <= y.len; i++){
            y.s[i] += s[i]+x.s[i];
            y.s[i+1] += y.s[i]/10;
            y.s[i] %= 10;
        }
        while (y.s[y.len+1] > 0){
            y.len++;
            y.s[y.len+1] += y.s[y.len]/10;
            y.s[y.len] %= 10;
        }
        return y;
    }
    void print(){
        for (int i = len; i >= 1; i--)
            putchar(s[i]+'0');
        putchar('\n');
    }
}f[N], g[N], delf[N], delg[N];



int main()
{
    scanf("%d", &n);
    f[1] = delf[1] = 1;
    g[1] = delg[1] = 0;
    for (int i = 2; i <= n; i++){
        delf[i] = delf[i-1]+f[i-1];
        f[i] = f[i-1]+delf[i];
        delg[i] = delg[i-1]+delf[i-1]+delf[i-1];
        g[i] = g[i-1]+delg[i];
    }
    (f[n]+g[n]).print();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xyyxyyx/article/details/82289451