首页 > 其他分享 >P4310 绝世好题

P4310 绝世好题

时间:2022-10-14 11:22:11浏览次数:62  
标签:绝世 leq int 样例 好题 整数 P4310

绝世好题

题目描述

给定一个长度为 \(n\) 的数列 \(a_i\),求 \(a_i\) 的子序列 \(b_i\) 的最长长度 \(k\),满足 \(b_i \& b_{i-1} \ne 0\),其中 \(2\leq i\leq k\), \(\&\) 表示位运算取与。

输入格式

输入文件共 2 行。
第一行包括一个整数 \(n\)。
第二行包括 \(n\) 个整数,第 \(i\) 个整数表示 \(a_i\)。

输出格式

输出文件共一行。
包括一个整数,表示子序列 \(b_i\) 的最长长度。

样例 #1

样例输入 #1

3
1 2 3

样例输出 #1

2

提示

对于100%的数据,\(1\leq n\leq 100000\),\(a_i\leq 10^9\)

解析

两个数&不等于0,则这两个数的二进制中至少有一位都是1,我们设\(f_i\)表示序列末尾的数二进制下第i位为1的最大长度(可能有点不好理解),对于每个数x,枚举他的每个二进制位,如果为1,则可以转移。
本题的DP有点神奇且抽象,思维难度还是比较高的。

代码

#include <bits/stdc++.h>
using namespace std;
int f[35], ans;
int main() {
	int n; cin >> n;
	for (int i = 1; i <= n; i ++) {
		int x; cin >> x;
		int k = 0; 
		for (int j = 0; j <= 30; j ++)
			if ((1 << j) & x) k = max(k, f[j] + 1);
		for (int j = 0; j <= 30; j ++)
			if ((1 << j) & x) f[j] = k;
		ans = max(ans, k);
	}
	cout << ans << '\n';
}

image

标签:绝世,leq,int,样例,好题,整数,P4310
From: https://www.cnblogs.com/YHxo/p/16791045.html

相关文章

  • 一些好题
    P3034不是很常规的题目。考虑奶牛之间的相对位置。因为一头奶牛最多跳出来一次,所以两头奶牛的相对位置最多改变两次。这样就可以求出任意两头奶牛的相对位置。这样的......
  • P4310 绝世好题
    //dp:二进制的每一位的最大子序列#include<bits/stdc++.h>usingnamespacestd;intn,a[100001];intans=0;intmain(){ cin>>n; for(inti=1;i<=n;i++) { i......
  • AGC038C LCMs 详解(莫比乌斯反演好题)
    ProblemAGC038C给定一个长为\(n\)的序列\(A_1,A_2,\cdots,A_n\),求\(\sum_{i=1}^{n}{\sum_{j=i+1}^{n}{lcm(A_i,A_j)}}\bmod998244353\)\(n\leq2\times10^5,A_i......
  • Timus Online Judge 1005. Stone Pile——01背包好题
    题目1005.StonePile@TimusOnlineJudge就是给你一组堆石头,分成两组,叫你求两组重量差的最小值思路这道题解法很巧妙,用01背包来解决dp[i][j]:表示前i个物品里面,花......