【BZOJ 1002】[FJOI2007]轮状病毒
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1002
【题意】
让你把这个图通过删边操作搞成一棵树;
问方案数;
【题解】
先写个小规模的爆搜然后找规律;
(爆搜程序在最下面)
a[1..10]=
1
5
16
45
121
320
841
2205
5776
15125
就猜呗;
设x*a[n-1]+y*a[n-2]+z=a[n]
然后把前3个带去进去;
{
5x+y+z=16
16x+5y+z=45
45x+16y+z=121
}
x=3
y=-1
z=2;
a[n] = 3*a[n-1]-a[n-2]+2;
a[1] = 1;
a[2] = 5;
得到递推式之后;
写个单精度乘高精度+单晶加高精+高精减就好;
【完整代码】
/**************************************************************
Problem: 1002
User: chengchunyang
Language: C++
Result: Accepted
Time:0 ms
Memory:1336 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int MAXN = 110;
struct abc
{
int a[MAXN],len;
void init()
{
rep1(i,1,100)
a[i] = 0;
}
};
abc f[MAXN];
int n;
void sub(abc &a,abc &b)
{
rep1(i,1,a.len)
a.a[i]-=b.a[i];
rep1(i,1,a.len)
if (a.a[i]<0)
{
a.a[i]+=10;
a.a[i+1]--;
}
int &t = a.len;
while (a.a[t]==0) t--;
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
rep1(i,1,100) f[i].init();
f[1].a[1] = 1,f[1].len = 1;
f[2].a[1] = 5,f[2].len = 1;
rep1(i,3,100)
{
//f[i] = 3*f[i-1]-f[i-2]+2;
abc t = f[i-1];
int &len = t.len;
int x = 0;
rep1(j,1,len)
{
t.a[j]=t.a[j]*3+x;
x = t.a[j]/10;
t.a[j]%=10;
}
while (x>0)
{
len++;
t.a[len]=x;
x=t.a[len]/10;
t.a[len]%=10;
}
t.a[1]+=2;
rep1(j,1,len)
{
t.a[j+1] += t.a[j]/10;
t.a[j]%=10;
}
if (t.a[len+1]>0)
len++;
sub(t,f[i-2]);
f[i] = t;
}
rei(n);
rep2(i,f[n].len,1)
printf("%d",f[n].a[i]);
return 0;
}
//爆搜程序
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int MAXN = 1100;
int n,tot,sta[MAXN],f[MAXN],ans = 0;
pii bian[MAXN];
bool bo[MAXN];
int ff(int x)
{
if (f[x]==x) return x;
else
return f[x] = ff(f[x]);
}
void dfs(int x,int xx)
{
if (x>n)
{
rep1(i,0,n)
f[i] = i;
rep1(i,1,n)
{
int idx = sta[i];
int x = bian[idx].fi,y = bian[idx].se;
int r1 = ff(x),r2 = ff(y);
if (r1!=r2)
f[r1]=r2;
else
return;
}
ans++;
return;
}
rep1(i,xx+1,tot)
{
sta[x] = i;
dfs(x+1,i);
}
}
int main()
{
freopen("F:\\rush.txt","r",stdin);
freopen("F:\\rush_out.txt","w",stdout);
while(cin>>n)
{
ans = 0;
tot = 2*n;
rep1(i,1,n)
{
bian[i].fi = i,bian[i].se = 0;
int x = i,y = i+1;
if (y==n+1) y=1;
bian[n+i].fi = x,bian[n+i].se = y;
}
dfs(1,0);
cout << ans << endl;
}
return 0;
}