zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 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

    Solution

    一眼就是基尔霍夫矩阵啊
    但是似乎有更优秀的解法?
    直接递推,递推式:(F(i)=3F(i-1)-F(i-2)+2~~(F(1)=1,F(2)=5))
    证明
    然后写个高精度

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=100+10;
    int n;
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    struct Bnum{
    	int a[MAXN],len;
    	inline void init(int x)
    	{
    		memset(a,0,sizeof(a));
    		len=0;
    		while(x)a[++len]=x%10,x/=10;
    	}
    	inline Bnum operator + (const Bnum &A) const {
    		Bnum B;
    		B.init(0);
    		B.len=max(len,A.len);
    		for(register int i=1;i<=B.len;++i)
    		{
    			B.a[i]+=a[i]+A.a[i];
    			B.a[i+1]+=B.a[i]/10;
    			B.a[i]%=10;
    		}
    		if(B.a[B.len+1])B.len++;
    		return B;
    	};
    	inline Bnum operator - (const Bnum &A) const {
    		Bnum B;
    		B.init(0);
    		B.len=max(len,A.len);
    		for(register int i=1;i<=len;++i)
    		{
    			B.a[i]+=a[i]-A.a[i];
    			if(B.a[i]<0)B.a[i]+=10,B.a[i+1]--;
    		}
    		while(B.len&&!B.a[B.len])B.len--;
    		return B;
    	};
    	inline void print()
    	{
    		for(register int i=len;i>=1;--i)write(a[i]);
    		puts("");
    	}
    };
    Bnum ans,las,mlas,two,tmp;
    int main()
    {
    	read(n);
    	if(n==1)write(1,'
    ');
    	else if(n==2)write(5,'
    ');
    	else
    	{
    		las.init(5);mlas.init(1);two.init(2);
    		for(register int i=3;i<=n;++i)ans=las+las+las-mlas+two,mlas=las,las=ans;
    		ans.print();
    	}
    	return 0;
    }
    
  • 相关阅读:
    Codeforces Round #461 (Div. 2)B-Magic Forest+位运算或优雅的暴力
    动态规划:树形DP
    动态规划:划分DP
    动态规划:状压DP
    图论:树的直径
    图论:点分治
    图论:2-SAT
    数据结构&图论:K短路-可持久化可并堆
    图论:次短路
    图论:曼哈顿距离最小生成树
  • 原文地址:https://www.cnblogs.com/hongyj/p/9194441.html
Copyright © 2011-2022 走看看