一眼看到数据范围,输入只有1个n,n<100果断打表。然而好像跑表的复杂度不兹磁啊,要跑几年。所以要打表找规律。
#include<iostream>//这是小数据打表
#include<cstdio>
using namespace std;
struct E{int f,t;}b[100005];
int cnt,n;
int use[100005];
int fa[100005];
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);}
int ans;
void dfs(int x,int k)
{
if(k==n)
{
for(int i=0;i<=n;i++)
fa[i]=i;
bool h=1;
for(int i=1;i<=k;i++)
{
int p=use[i];
int x=b[p].f,y=b[p].t;
if(find(x)!=find(y))
fa[find(x)]=find(y);
else {h=0;break;}
}
if(h) ans++;
return ;
}
if(x>cnt) return ;
use[k+1]=x;
dfs(x+1,k+1);
dfs(x+1,k);
}
int main()
{
for(n=1;n<=100;n++)
{
ans=0;cnt=0;
for(int i=1;i<n;i++)
b[++cnt]=(E){i,i+1};
b[++cnt]=(E){n,1};
for(int i=1;i<=n;i++)
b[++cnt]=(E){0,i};
dfs(1,0);cout<<n<<" "<<ans<<endl;
}
}
/*
1 1
2 5
3 16
4 45
5 121
6 320
7 841
8 2205
9 5776
10 15125
11 39601
12 103680
13 271441
14 710645
15 1860496
16 4870845
17 12752041
18 33385280
*/
我打出n<=17的答案,想起在某学堂讲过自动找规律机,但我当时在颓废,于是硬生生的用眼瞪出了规律,合理猜想,大胆假设。对于奇数,答案都是某个数c【i】的平方。c[i]=c[i-2]*3-c[i-4];
对于偶数,答案是某个数c[i]除以5,c[i]=c[i-2]*7-c[i-4]+2;
然后是高精度。
#include<iostream>
#include<cstdio>
using namespace std;
struct Big
{
int a[10005];
int x;
void print()
{
bool pr=0;
for(int i=x+100;i>=1;i--)
if(a[i]||pr)printf("%d",a[i]),pr=1;
}
void pre()
{
for(int i=1;;i++)
{
if(i>x&&a[i]==0)
{
x=i-1;
break;
}
if(a[i]>9)
{
a[i+1]+=a[i]/10;
a[i]%=10;
}
}
}
}f[105];
Big operator *(Big A,int b)
{
int x=A.x;
for(int i=1;i<=x;i++)
A.a[i]*=b;
A.pre();
return A;
}
Big zero;
Big operator *(Big A,Big B)
{
Big C=zero;
for(int i=1;i<=A.x;i++)
for(int j=1;j<=B.x;j++)
C.a[i+j-1]+=A.a[i]*B.a[j];
C.x=A.x+B.x;
C.pre();
return C;
}
Big operator -(Big A,Big B)
{
for(int i=1;i<=A.x;i++)
{
A.a[i]-=B.a[i];
if(A.a[i]<0)
{
A.a[i+1]--;
A.a[i]+=10;
}
}int x=0;
for(int i=A.x;i>=1;i--)
{
if(A.a[i])
{
x=i;
break;
}
}
A.x=x;
return A;
}
int main()
{
int n;
scanf("%d",&n);
f[1].a[1]=1;f[3].a[1]=4;
f[2].a[1]=1;f[4].a[1]=9;
for(int i=1;i<=4;i++)
f[i].x=1;
if(n%2)
{
for(int i=5;i<=n;i+=2)
f[i]=f[i-2]*3-f[i-4];
f[n]=f[n]*f[n];
f[n].print();
}
else
{
for(int i=6;i<=n;i+=2)
{
f[i]=f[i-2]*7-f[i-4];
f[i].a[1]+=2;
f[i].pre();
}
f[n]=f[n]*5;
f[n].print();
}
return 0;
}