您的位置:首页 > 其它

【斐波那契数列】51Nod 1350 斐波那契表示

2017-09-13 21:18 330 查看
题面在这里

一道神奇的数学题……

首先需要了解:将一个数每次减去最大可减的斐波那契数,一定是最优的方案之一

以下用fi表示斐波那契数列的第i项

则有:

Gfi−1=Gfi−1−1+Gfi−fi−1−1+fi−fi−1⇒Gfi−1=Gfi−1−1+Gfi−2−1+fi−2

于是我们可以预处理出fi,以及Gi的一些特殊位置

现在询问任意Gn(以下记为Sum(n)),其实一样的思路,设m为小于n的最大的斐波那契数

Sum(n)=Sum(n−m)+n−m+1+Gm

由于斐波那契数列是接近于指数增长的,所以可以看做O(log2n)的复杂度(二分找mO(logn))

当然,程序实现时用Gi代表Gfi−1

示例程序:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=105;
typedef long long LL;
LL tst,n,nn,f[maxn],G[maxn];
LL sum(LL n){
if (n<=3) return n;
int i=upper_bound(f,f+1+nn,n)-f-1;
return G[i]+sum(n-f[i])+n-f[i]+1;
}
int main(){
f[0]=0;f[1]=f[2]=1;f[3]=2;
G[1]=G[2]=0;G[3]=1;
for (int i=4;;i++){
f[i]=f[i-1]+f[i-2];
G[i]=G[i-1]+G[i-2]+f[i-2];
if (f[i]>1e17) {nn=i;break;}
}
scanf("%lld",&tst);
while (tst--)
scanf("%lld",&n),printf("%lld\n",sum(n));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: