其他分享
首页 > 其他分享> > 代码源每日一题 最长有趣子序列

代码源每日一题 最长有趣子序列

作者:互联网

最长有趣子序列

题目描述

定义一个序列是有趣的当且仅当他相邻两项的与不为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