【斐波那契数列】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
示例程序:
一道神奇的数学题……
首先需要了解:将一个数每次减去最大可减的斐波那契数,一定是最优的方案之一
以下用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; }
相关文章推荐
- 51nod 1350 斐波那契表示【斐波那契数列】
- 51nod 1350 斐波那契表示(打表+找规律)
- 51nod 1350 斐波那契表示(规律)
- 51nod 1350 斐波那契表示
- 51Nod-1350-斐波那契表示
- [斐波那契拆分 乱搞 数学] 51Nod 1350 斐波那契表示
- 51nod-1350 斐波那契表示(规律)
- 51nod 1350 斐波那契表示
- 51nod-1350:斐波那契表示
- 51nod 1350 斐波那契表示 (数学)
- 51nod-斐波那契表示(找规律)
- 51nod 1031 骨牌覆盖 斐波那契数列
- 51nod_1242 斐波那契数列的第N项
- 51nod 1282 时钟 哈希+最小表示法+map
- 51nod 1195 斐波那契数列的循环节【斐波那契数列&&二次剩余&&欧拉判定准则】
- 51nod 1355 斐波那契的最小公倍数
- 51nod 1242 斐波那契数列第N项
- 51nod 1242 斐波那契数列的第N项(O(logn)求递推式)
- 51nod 1365 Fib(N) mod Fib(K) & 蓝桥杯 斐波那契(数论)
- [网易2012年某笔试题] 求斐波那契数列, 要求时间复杂度尽可能小(简单题,不熟悉斐波那契的同学可参考)