代码源每日一题 最长有趣子序列
作者:互联网
最长有趣子序列
题目描述
定义一个序列是有趣的当且仅当他相邻两项的与不为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;
}
标签:int,leq,ans,序列,table,有趣,最长 来源: https://www.cnblogs.com/zhaohanzheng/p/16152132.html