程式碼源每日一題 最長有趣子序列
阿新 • • 發佈:2022-04-16
最長有趣子序列
題目描述
定義一個序列是有趣的當且僅當他相鄰兩項的與不為0
即對一個長為\(n\)的序列\(\{a\}\), 滿足\(\forall x< n\ a[x]\&a[x+1] \neq 0\)
現在給你一個長為\(n\)的序列\(\{a\}\), 請問最長的有趣子序列的長度是多少
輸入描述
一行一個整數\(1\leq n \leq 10^6\)
接下來一行\(n\)個整數\(1 \leq a_i \leq 2^{31} - 1\)
輸出描述
一行一個整數, 用於描述最長有趣子序列的長度
樣例輸入
3
1 2 3
樣例輸出
2
題目分析
可以這樣考慮,\(table\)是這樣的一種陣列:
i=1,table=1b
i=2,table=10b
i=3,table=100b
i=4,table=1000b
i=4,table=10000b
......(以上都是二進位制)
也就是說,\(table[i]=1<<i\)。
設計一個ans陣列,表示\(\&table[i]!=0\)的數量的最大值,也就是對於每一位二進位制做\(dp\)。
\[ans[i]=\max_1^{40}(table[i]) \\table=max(ans,table) \]AC code
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e6+7; ll table[40],a[N]; int ans[40]; int main() { int n; scanf("%d",&n); for(int i = 1 ; i <= n ; i++ ) { scanf("%d",&a[i]); } for(int i = 0 ; i < 40 ; i++) table[i] = 1ll<<i; for(int i = 1 ; i <= n ; i++) { int t = 0; for(int j = 0 ; j < 32 ; j++) if(a[i]&table[j]) t = max(t,++ans[j]); for(int j = 0 ; j < 32 ; j++) if(a[i]&table[j]) ans[j] = t; } int res = 0; for(int i = 0 ; i < 32 ; i++) res = max(ans[i],res); cout << res; }