您的位置:首页 > 其它

bzoj 1002 [FJOI2007]轮状病毒 找规律/基尔霍夫矩阵

2015-01-04 19:48 309 查看

bzoj 1002 轮状病毒

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1002

Description

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



Input

第一行有1个正整数n。

Output

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

Sample Input

3

Sample Output

16

这是道递推的题,难点在于找规律,需要用到基尔霍夫矩阵
首先科普一下矩阵的转置:http://www.360doc.com/content/11/0906/15/7317486_146207073.shtml

通过基尔霍夫矩阵(生成树的计数)得出F(n) = 3 * F(n - 1) - F(n - 2) + 2,其中F(1)
= 1, F(2) = 5;
关于生成树计数:http://wenku.baidu.com/view/0c086741be1e650e52ea990e.html

还想看看另类证明:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/
高精度+递推

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>

using namespace std;

typedef long long ll;
struct Bignum{
static const int BASE=100000000;
static const int MIDTH=8;
vector<int >s;
Bignum (int num=0){*this=num;}
Bignum operator =(int num)
{
int num1=num;
if(num1!=0)
{
s.clear();
while(num1>0)
{
s.push_back(num1%BASE);
num1/=MIDTH;
}
}
else s.push_back(0);
return *this;
}

Bignum operator =(const string num)
{
s.clear();
int x,len=(num.length()-1)/MIDTH+1;
for(int i=0;i<len;i++)
{
int end=num.length()-i*MIDTH;
int start=max(0,end-MIDTH);
sscanf(num.substr(start,end-start).c_str(),"%d",&x);
s.push_back(x);
}
return *this;
}
Bignum operator +(const Bignum &b)const
{
Bignum t;
t.s.clear();
for(int i=0,g=0;;i++)
{
if(g==0&&i>s.size()&&i>b.s.size())
break;
int x=g;
if(i<s.size())
x+=s[i];
if(i<b.s.size())
x+=b.s[i];
t.s.push_back(x%BASE);
g=x/BASE;
}
return t;
}
Bignum operator -(const Bignum &b)const
{
Bignum t;Bignum th=*this;
t.s.clear();
for(int i=0,x;; i++)
{
if(i>=th.s.size())break;
if(i<=th.s.size()&&i>=b.s.size())
{
x=s[i];
}
else
{
if(th.s[i]<b.s[i])  th.s[i]+=BASE,th.s[i+1]=s[i+1]-1;
x=th.s[i]-b.s[i];
}
t.s.push_back(x);
}
return t;
}
Bignum operator *(const int num)const
{
Bignum t;
t.s.clear();
for(int i=0,g=0;;i++)
{
if(g==0&&i>s.size())  break;
int x=g;
x+=g;
x+=num*s[i];
t.s.push_back(x%BASE);
g=x/BASE;
}
return t;
}

};
ostream& operator <<(ostream &out,Bignum &b)
{
while(b.s.back()==0)
{
b.s.pop_back();
}
char bf[20];

sprintf(bf,"%08d",b.s.back());
int j=0;
while(bf[j]=='0')
{
j++;
}
for(int i=j; i<strlen(bf); i++)
out<<bf[i];
for(int i=b.s.size()-2; i>=0; i--)
{
char buf[20];
sprintf(buf,"%08d",b.s[i]);
for(int j=0; j<strlen(buf); j++)
out<<buf[j];
}
return out;
}
istream& operator >>(istream &in ,Bignum &b)
{
string x;
if(!(in>>x))return in;
b=x;
return in;

}
Bignum f[101];
int n;
int main()
{
scanf("%d",&n);
f[1]=1;f[2]=5;
Bignum d=2;
for(int i=3;i<=n;i++)
{
Bignum t=f[i-1]+f[i-1];
t=t+f[i-1];
t=t-f[i-2];
f[i]=t+d;
}
cout<<f
;

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: