可以证明每次选最大的fib数减去一定是最优解之一
然后预处理G[fib[i]-1]
额 代码横跨noip前后 意识模糊 一片mess
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
ll fib[205]; int maxn;
ll F[205];
inline ll Sum(ll n){
if (n==0) return 0;
if (n==1) return 1;
if (n==2) return 2;
ll ret=0;
int pos=upper_bound(fib,fib+maxn+1,n)-fib-1;
ret=F[pos]+Sum(n-fib[pos])+n-fib[pos]+1;
return ret;
}
int main(){
ll T,n;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
fib[0]=0; fib[1]=1;
F[2]=0; F[3]=1; F[4]=2;
for (int i=2;;i++){
fib[i]=fib[i-1]+fib[i-2];
if (fib[i]-1>2)
F[i]=F[i-1]+F[i-2]+fib[i-2];
maxn=i;
if (fib[i]>1e17) break;
}
scanf("%lld",&T);
while (T--)
scanf("%lld",&n),printf("%lld\n",Sum(n));
return 0;
}