zoukankan      html  css  js  c++  java
  • [FJOI2007]轮状病毒

    题目描述

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

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

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

    输入输出格式

    输入格式:

    第一行有1个正整数n。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    3
    
    输出样例#1: 复制
    16
    其实可以用矩阵树定理来算方案数
    但是没有取模,高精是必需的
    实际每个矩阵都是相似的
    1 5 16 45 121 320
    归纳找到规律:
    f[i]=3*f[i-1]-f[i-2]+2
    证明
    还有DP和高精度矩阵树(太毒了找不到)的做法
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 struct Num
     8 {
     9   int len;
    10   int a[1001];
    11 }f[101];
    12 int n;
    13 Num chen(Num a,int k)
    14 {
    15   int i;
    16     Num ans;
    17     for (i=1;i<=a.len;i++)
    18       ans.a[i]=a.a[i]*k;
    19     for (i=1;i<=a.len;i++)
    20       ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
    21     ans.len=a.len;
    22     while (ans.a[ans.len+1])
    23       {
    24     ans.len++;
    25     ans.a[ans.len+1]+=ans.a[ans.len]/10;
    26     ans.a[ans.len]%=10;
    27       }
    28     return ans;
    29 }
    30 Num add(Num a,int k)
    31 {
    32   int i;
    33     Num ans;
    34     for (i=1;i<=a.len;i++)
    35       ans.a[i]=a.a[i];
    36     ans.len=a.len;
    37     ans.a[1]+=k;
    38     for (i=1;i<=a.len;i++)
    39       ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
    40     while (ans.a[ans.len+1])
    41       {
    42     ans.len++;
    43     ans.a[ans.len+1]+=ans.a[ans.len]/10;
    44     ans.a[ans.len]%=10;
    45       }
    46     return ans;
    47 }
    48 Num jian(Num a,Num b)
    49 {
    50   int i;
    51     Num ans;
    52     ans.len=a.len;
    53     for (i=1;i<=b.len;i++)
    54       ans.a[i]=a.a[i]-b.a[i];
    55     for (i=b.len+1;i<=a.len;i++)
    56       ans.a[i]=a.a[i];
    57     for (i=1;i<=a.len;i++)
    58       {
    59     if (ans.a[i]<0) ans.a[i]+=10,ans.a[i+1]-=1;
    60       }
    61     while (ans.a[ans.len]&&ans.len>1) ans.len--;
    62     return ans;
    63 }
    64 int main()
    65 {int i,j;
    66   cin>>n;
    67   f[1].a[1]=1;f[1].len=1;
    68   f[2].a[1]=5;f[2].len=1;
    69   for (i=3;i<=n;i++)
    70     {
    71       f[i]=chen(f[i-1],3);
    72       f[i]=jian(f[i],f[i-2]);
    73       f[i]=add(f[i],2);
    74     }
    75   for (i=f[n].len;i>=1;i--)
    76     printf("%d",f[n].a[i]);
    77 }
  • 相关阅读:
    C++11写算法之顺序查找
    Codeforces Round #632 (Div. 2) 题解
    AtCoder Beginner Contest 161 题解
    Codeforces Round #630 (Div. 2) 部分题解
    2019-2020 ICPC Northwestern European Regional Programming Contest (NWERC 2019) 部分题解
    Codeforces Round #629 (Div. 3) 题解
    Educational Codeforces Round 84 (Rated for Div. 2) 部分题解
    AtCoder Beginner Contest 159 题解
    Codeforces Round #628 (Div. 2) 题解
    Codeforces Round #627 (Div. 3) 题解
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8458831.html
Copyright © 2011-2022 走看看