问题
分析
f[n]代表由n条边组成一条直线,其中的匹配(没有公共点的边集)个数,d[n]表示n条边组成一个圈,其中的匹配个数,所以
d
[
n
]
=
f
[
n
−
1
]
+
f
[
n
−
3
]
d[n]=f[n-1]+f[n-3]
d[n]=f[n−1]+f[n−3],不选最后一条边就是
f
[
n
−
1
]
f[n-1]
f[n−1],选了就是
f
[
n
−
3
]
f[n-3]
f[n−3],其中
f
[
n
]
=
f
[
n
−
1
]
+
f
[
n
−
2
]
f[n]=f[n-1]+f[n-2]
f[n]=f[n−1]+f[n−2]
f=1,2,3,5,8(从序号1开始)
d=4,7,11(从序号3开始),可以看出d也是两个和等于第三个,考虑规律
于是,
d
[
n
]
=
f
[
n
−
1
]
+
f
[
n
−
3
]
,
d
[
n
−
1
]
=
f
[
n
−
2
]
+
f
[
n
−
4
]
,
d
[
n
−
2
]
=
f
[
n
−
3
]
+
f
[
n
−
5
]
d[n]=f[n-1]+f[n-3],d[n-1]=f[n-2]+f[n-4],d[n-2]=f[n-3]+f[n-5]
d[n]=f[n−1]+f[n−3],d[n−1]=f[n−2]+f[n−4],d[n−2]=f[n−3]+f[n−5],然后合并得到
d
[
n
]
=
d
[
n
−
1
]
+
d
[
n
−
2
]
d[n]=d[n-1]+d[n-2]
d[n]=d[n−1]+d[n−2]
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
const LL maxn=10000+1,Inf=0x3f3f3f3f,mod=100000000;
//vector<int> d[maxn];
struct Number{
vector<int> v;
int n;
Number():n(0){}
Number(int x){
while(x){
v.push_back(x%mod);
x/=mod;
}
n=v.size();
}
Number operator + (const Number &rhs) const {
Number temp;
int t=max(n,rhs.n),a=0,res;
for(int i=0;i<t;++i){
if(i<n && i<rhs.n){
res=v[i]+rhs.v[i]+a;
}else if(i<n){
res=v[i]+a;
}else if(i<rhs.n){
res=rhs.v[i]+a;
}
temp.v.push_back(res%mod);
a=res/mod;
}
if(a>0) temp.v.push_back(a);
temp.n=temp.v.size();
return temp;
}
}d[maxn];
int main(void){
d[3]=Number(4);
d[4]=Number(7);
for(int i=5;i<maxn;++i){
d[i]=d[i-1]+d[i-2];
}
int k;
while(scanf("%d",&k)==1 && k){
printf("%d",d[k].v.back());
for(int i=d[k].n-2;i>=0;--i){
printf("%08d",d[k].v[i]);
}
printf("\n");
}
}