• 1002: [FJOI2007]轮状病毒


    Description

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

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

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

    Input

      第一行有1个正整数n

    Output

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

    Sample Input

    3

    Sample Output

    16
     
    //一开始非常nb地推了个组合数的公式,但是要写高精阶乘 高精除高精,就没写
    //然后就写longlong看看能过几个点
    //A掉一个点,和题解对了下,发现只有n<=3的时候是对的 
    
    //不会别的做法,看了题解。
    //有矩阵树定理的做法和递推的做法
    //感觉递推的比较好写,不用写高精乘法
    //将n<=5的ans写出来,可以发现f[n]=3*f[n-1]-f[n-2]+2
    //其实上面那个式子是个斐波那契的变形,整理一下可以得到这个式子 
    
    //不可避免地要写高精 
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n;
    int ans[105][1005];
    int len[105];
    int mul[1005];
    
    void calc(int x)
    {
        int m=x-2,n=x-1;
        int cnt=0;int l=len[n];
        for(int i=1;i<=l;++i)
        {
            mul[i]=(3*ans[n][i]+cnt)%10;
            cnt=(3*ans[n][i]+cnt)/10;
        }
        if(cnt)
            mul[++l]=cnt;
        cnt=2;
        for(int i=1;i<=l;++i)
        {
            ans[x][i]=(mul[i]-ans[m][i]+cnt+10)%10;
            if(mul[i]-ans[m][i]+cnt<0)
                cnt=-1;
            else
                cnt=(mul[i]-ans[m][i]+cnt)/10;
        }
        if(cnt)
            ans[x][l+1]=cnt,len[x]=l+1;
        else
            len[x]=l;
        return;
    }
    
    int main()
    {
        scanf("%d",&n);
        ans[1][1]=1,len[1]=1;
        ans[2][1]=5,len[2]=1;
        for(int i=3;i<=n;++i)
            calc(i);
        for(int i=len[n];i;--i)
            cout<<ans[n][i];
        return 0;
    }
  • 相关阅读:
    Git学习-创建版本库
    使用Vim编辑器,如何退出
    设置既定目录的命令提示符
    字符数组和字符串
    一波杂乱的分享
    全国软件设计大赛C/C++语言练习
    HDU 1720、1062、2104、1064、2734、1170、1197、2629
    hdu 2000-2010 ACM
    HDU——算法练习1000 1089-1096
    爬虫学习笔记之为什么要设置超时时间,怎么设置(使用selenium)
  • 原文地址:https://www.cnblogs.com/lovewhy/p/9633762.html
Copyright © 2020-2023  润新知