zoukankan      html  css  js  c++  java
  • ASC7 Problem C. Fibonacci Subsequence

    题目大意

    给你一个长为$m(mle 3000)$的数列,求最长Fibonacci子序列。

    简要题解

    DP即可,因为头两个随便选,所以考虑设$f[i][j]$表示以$a_i,a_j$开始的Fibonacci子序列最长长度为多少,只需要从$f[j][k],a_k=a_i+a_j$转移,关键在于找到$k$,map和hash_map都TLE了,最后手写了一个HashTable,Accept。

    有一个细节就是转移的顺序,先从后往前枚举第一维$i$,再从$i-1$到$0$枚举第二维$j$,就可以避免每次清空HashTable。

    输出答案没必要保存DP信息(不然会MLE),直接由Fibonacci前两项就可以全部推出来了,我个智障。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 namespace my_header {
      4 #define pb push_back
      5 #define mp make_pair
      6 #define pir pair<int, int>
      7 #define vec vector<int>
      8 #define pc putchar
      9 #define clr(t) memset(t, 0, sizeof t)
     10 #define pse(t, v) memset(t, v, sizeof t)
     11 #define bl puts("")
     12 #define wn(x) wr(x), bl
     13 #define ws(x) wr(x), pc(' ')
     14     const int INF = 0x3f3f3f3f;
     15     typedef long long LL;
     16     typedef double DB;
     17     inline char gchar() {
     18         char ret = getchar();
     19         for(; (ret == '
    ' || ret == '
    ' || ret == ' ') && ret != EOF; ret = getchar());
     20         return ret; }
     21     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
     22         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
     23         if (c == '-') { flg = -1; c = getchar(); }
     24         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
     25             ret = ret * 10 + c - '0';
     26         ret = ret * flg; }
     27     inline int fr() { int t; fr(t); return t; }
     28     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
     29     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
     30     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
     31         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
     32             (wr(a/b, b, 0), pc('0' + a % b)));
     33     }
     34     template<class T> inline void wt(T a) { wn(a); }
     35     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
     36     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
     37     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
     38     template<class T> inline T gcd(T a, T b) {
     39         return b == 0 ? a : gcd(b, a % b); }
     40     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
     41         for(; i; i >>= 1, b = b * b % _m)
     42             if(i & 1) r = r * b % _m;
     43         return r; }
     44 };
     45 using namespace my_header;
     46 
     47 const int MAXN = 3000 + 3;
     48 int a[MAXN], n;
     49 short f[MAXN][MAXN];
     50 
     51 struct HashTable {
     52     static const int MOD = 100019;
     53     static const int HASHSIZE = 3333;
     54     int h[MOD], nxt[HASHSIZE], key[HASHSIZE], val[HASHSIZE], cnt;
     55     HashTable() {
     56         memset(h, -1, sizeof h);
     57         cnt = 0;
     58     }
     59     int getHash(int p) {
     60         return (p % MOD + MOD) % MOD;
     61     }
     62     void insert(int k, int v) {
     63         int t = getHash(k);
     64         val[cnt] = v;
     65         key[cnt] = k;
     66         nxt[cnt] = h[t];
     67         h[t] = cnt++;
     68     }
     69     int find(int k) {
     70         int t = getHash(k);
     71         for (int i = h[t]; i != -1; i = nxt[i]) {
     72             if (key[i] == k)
     73                 return val[i];
     74         }
     75         return 0;
     76     }
     77 } pos;
     78 
     79 int main() {
     80 #ifdef lol
     81     freopen("C.in", "r", stdin);
     82     freopen("C.out", "w", stdout);
     83 #else
     84     freopen("fibsubseq.in", "r", stdin);
     85     freopen("fibsubseq.out", "w", stdout);
     86 #endif
     87     fr(n);
     88     for (int i = 1; i <= n; ++i)
     89         fr(a[i]);
     90     for (int i = n; 0 < i; --i) {
     91         for (int j = i - 1; 0 < j; --j) {
     92             int t = pos.find(a[i] + a[j]);
     93             if (f[i][t] + 1 > f[j][i])
     94                 f[j][i] = f[i][t] + 1;
     95         }
     96         pos.insert(a[i], i);
     97     }
     98     int ans = 0, ri, rj;
     99     for (int i = 1; i <= n; ++i)
    100         for (int j = i + 1; j <= n; ++j)
    101             if (f[i][j] >= ans) {
    102                 ans = f[i][j];
    103                 ri = a[i];
    104                 rj = a[j];
    105             }
    106     wt(ans + 1);
    107     if (ans == 0) {
    108         wt(a[1]);
    109         return 0;
    110     }
    111     for (int i = 0; i <= ans; ++i) {
    112         ws(ri);
    113         int t = ri + rj;
    114         ri = rj;
    115         rj = t;
    116     }
    117     puts("");
    118 
    119     return 0;
    120 }
  • 相关阅读:
    Genymotion安装与集成开发指南
    近期遇到的Android问题解决与总结
    关于Android Studio乱码的解决办法
    菜鸟程序员如何才能快速提高自己的技术
    android不能调试解决方法
    导入工程出现@Override错误
    读取本地文件的权限问题
    混合app开发
    JNI 实战全面解析
    Android性能优化
  • 原文地址:https://www.cnblogs.com/ichn/p/6404446.html
Copyright © 2011-2022 走看看