題目來源: PRoject Euler基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題
收藏
關(guān)注每一個正整數(shù)都可以表示為若干個斐波那契數(shù)的和,一個整數(shù)可能存在多種不同的表示方法,例如:14 = 13 + 1 = 8 + 5 + 1,其中13 + 1是最短的表示(只用了2個斐波那契數(shù))。定義F(n) = n的最短表示中的數(shù)字個數(shù),F(xiàn)(14) = 2,F(xiàn)(100) = 3(100 = 3 + 8 + 89),F(xiàn)(16) = 2(16 = 8 + 8 = 13 + 3)。定義G(n) = F(1) + F(2) + F(3) + ...... F(n),G(6) = 1 + 1 + 1 + 2 + 1 + 2 = 8。給出若干個數(shù)字n,求對應(yīng)的G(n)。Input第1行:一個數(shù)T,表示后面用作輸入測試的數(shù)的數(shù)量(1 <= T <= 50000)。第2 - T + 1行:每行1個數(shù)n(1 <= n <= 10^17)。Output輸出共T行:對應(yīng)每組數(shù)據(jù)G(n)的值。Input示例3136Output示例138李陶冶 (題目提供者)題目淺顯易懂,n很大,呢就是硬著頭皮找規(guī)律了,這道題的規(guī)律不好一眼看出,甚至在紙上表示出前10項也沒看先端倪,搜了一發(fā)題解,發(fā)現(xiàn)仍是規(guī)律,不過比較難看出,因此直接采用了結(jié)論。這里只是簡單較少下結(jié)論好了。首先需要說的是一個數(shù)能用最少的斐波那契數(shù)表示的話一定包括當前能組成該數(shù)的最大斐波那契數(shù),想到這里,剩下的就是簡單打表找規(guī)律了for example :i=6時的fib[i]=13,從13開始的fib[i-1]項的最少斐波那契數(shù)為1,2,2,2,3,2,3,3, 可以發(fā)現(xiàn)前5項 正好和F[8],F[9],F[10],F[11],F[12]一樣后3項為F[5]+1,F[6]+1,F[7]+1;根據(jù)這個規(guī)律 定義A[i]為 從f[i]開始的連續(xù)f[i-1]項 的最短表示F[t] 的和,也就是A[i]=G[ f[i+1] -1]-G[f[i]-1]易知,A[1]=A[2]=1,A[i]=A[i-1]+A[i-2]+f[i-3]
#include<stdio.h>#include<algorithm>using namespace std;#define maxn 90typedef long long ll;ll fib[maxn],g[maxn];ll work(ll n){ int x; for(int i=0;i<maxn;i++) if(fib[i]>=n) { x=i; break; } if(fib[x]==n) return g[x]; x--; return g[x]+work(n-fib[x])+n-fib[x];}int main(){ int T,i; ll n; fib[0]=fib[1]=1; g[0]=g[1]=1; for(i=2;i<maxn;i++) { fib[i]=fib[i-1]+fib[i-2]; g[i]=g[i-1]+g[i-2]+fib[i-2]-1; } scanf("%d",&T); while(T--) { scanf("%lld",&n); printf("%lld/n",work(n)); }}
新聞熱點
疑難解答