1. 程式人生 > >【Henu ACM Round #13 F】Fibonacci-ish

【Henu ACM Round #13 F】Fibonacci-ish

我們 cpp tdi fine color blog lac ++ 個數字

【鏈接】 我是鏈接,點我呀:)
【題意】


在這裏輸入題意

【題解】


枚舉序列的頭兩個數字是什麽
O(N^2)
然後頭兩個數字確定之後。
f[3],f[4]..就確定了
只需查看f[3],f[4]..是不是存在就好了。
但是這樣復雜度看起來是O(N^3)的了。

其實不然,a[n] = a[n-1]+a[n-2]這個遞推的增長速度是接近2^n的增長速度的。
(所以到達10^9之後直接break就好了
所以實際上不會真的達到遞推1000的規模
差不多只有O(N^2*100)的樣子。
這是可以接受的了。

->但是有一種情況要特判,就是f[1] = f[2]=0的情況。這種情況直接統計1的個數即可。

程序中還加了一個優化。
因為前兩項f1,f2確定之後f[i] = xf1+yf2
則我們提前算出來系數。
就能直接得到前兩項是f1,f2的前提下fi的值了
根據這個可以做一下剪枝。

【代碼】

#include <bits/stdc++.h>
using namespace std;

const int N = 1000;

int a[N+10],n,b[N+10];
map<int,int> dic;
int x[N+10],y[N+10];

int main(){
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt"
, "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); x[1] = 1;y[1] = 0; x[2] = 0;y[2] = 1; x[3] = y[3]= 1; for (int i = 4;i <=N;i++){ x[i] = x[i-2]+x[i-1]; y[i] = y[i-2]+y[i-1]; } cin >> n; for (int i = 1;i <= n;i++) { cin >> a[i]; dic[a[i]]++; } int
ans = 2; for (int i = 1;i <= n;i++) for (int j = 1;j <= n;j++) if (i!=j){ if (a[i]==0 && a[j]==0){ int num = dic[0]; ans = max(ans,num); continue; } dic[a[i]]--,dic[a[j]]--; int num = 2; b[1] = a[i],b[2] = a[j]; if (ans>2 && ans<=40){ long long temp = 1LL*x[ans]*a[i]+1LL*y[ans]*a[j]; if (abs(temp)>1e9|| dic[temp]==0){ dic[a[i]]++,dic[a[j]]++; continue; } } for (int k = 3;k<=n;k++){ b[k] = b[k-2]+b[k-1]; if (abs(b[k])>1e9) break; if (dic[b[k]]>0){ dic[b[k]]--; num++; }else break; } ans =max(ans,num); for (int k = 1;k <= num;k++) dic[b[k]]++; } cout << ans << endl; return 0; }

【Henu ACM Round #13 F】Fibonacci-ish