zoukankan      html  css  js  c++  java
  • 51nod 1350 斐波那契表示 (找规律递推)

    分析: - -! 找规律。。。首先可以归纳证明,对于n,最佳的取法是先取不大于n的最大的那个斐波那契数,然后递推.从而可以得到算出F(n)的一个方法,但是n的范围太大了,先算出n较小的情况,会发现:

    第三列为F(n),第二列为G(n),可以看出第k块是由k-1块和k-2块+1合在一起得到的,从而可以先预处理前k块之和(k不会超过100),然后对于每个n,先找到最大的不超过n的那块,然后对剩下的项递归,总的复杂度为O(T*logn).

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 typedef unsigned long long ull;
     5 ull n,len=0;
     6 ull Fibo[1000000],maxn=100000000000000005;
     7 struct _B{
     8     ull sum,len,total;
     9 }B[100];
    10 void CalFibo(){
    11     Fibo[0]=Fibo[1]=1;
    12     Fibo[2]=2;
    13     B[1].len=1;B[1].sum=1;B[1].total=1;
    14     B[2].len=1;B[2].sum=1;B[2].total=2;
    15     //B[3].len=2;B[3].sum=3;B[3].total=5;
    16     len=3;
    17     for(int i=3;;i++,len++){
    18         Fibo[i]=Fibo[i-1]+Fibo[i-2];
    19         //if(i==3)continue;
    20         B[i].sum=B[i-1].sum+B[i-2].sum+Fibo[i-1]-Fibo[i-2];
    21         B[i].len=B[i-1].len+B[i-2].len;
    22         B[i].total=B[i-1].total+B[i].sum;
    23         if(Fibo[i]>maxn)break;
    24     }
    25 }
    26 ull devide(ull v,int l,int r){
    27     if(r-l<=1){
    28         if(Fibo[r]<=v)return r;
    29         return l;
    30     }
    31     int t=(l+r)/2;
    32     if(Fibo[t]==v)return t;
    33     if(Fibo[t]>v)return devide(v,l,t);
    34     return devide(v,t,r);
    35 }
    36 //int CalF(int k){
    37 //    int cnt=0;
    38 //    while(k){
    39 //        k-=Fibo[devide(k,0,len)];
    40 //        cnt++;
    41 //    }
    42 //    return cnt;
    43 //}
    44 ull dp(int k,ull num){
    45     if(k<=0)return 0;
    46     if(k<=2)return 1;
    47     while(k>1&&B[k-1].len>=num)k--;
    48     ull c1=B[k-1].sum;
    49     ull c2=dp(k-2,num-B[k-1].len)+num-B[k-1].len;
    50     return c1+c2;
    51 }
    52 ull solve(){
    53     ull k=n,f=devide(k,0,len-1);
    54     ull ans=B[f-1].total;
    55     k-=Fibo[f]-1;
    56     ans+=dp(f,k);
    57     return ans;
    58 }
    59 int main(){
    60     CalFibo();
    61     int t;
    62     cin>>t;
    63 //    int g=0;
    64 //    for(int i=1;i<=50;i++){
    65 //        if(CalF(i)==1)cout<<endl;
    66 //        cout<<i<<' '<<(g+=CalF(i))<<' '<<CalF(i)<<endl;
    67 //    }
    68     while(t--){
    69         cin>>n;
    70         cout<<solve()<<endl;
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    webapi 导入CSV文件
    webapi 导出CSV文件
    .net 压缩文件夹和解压
    SSH免密码登陆以及穿越跳板机
    hbase shell删除键不听使唤
    百度分享插件wbuid属性无法@指定微博
    iOS safari BUG 总结
    论zeroclipboard的各种爽翻天用法
    Android Studio 使用技巧
    安装第三方包web.py发生的错误
  • 原文地址:https://www.cnblogs.com/7391-KID/p/6903311.html
Copyright © 2011-2022 走看看