首页 > 其他分享 >最长

最长

时间:2024-08-13 21:55:09浏览次数:5  
标签:cnt int luogu www com 最长

https://www.luogu.com.cn/problem/P4310 第2题     最长 查看测评数据信息

给定一个长度是n的序列a[1,2,...n],现在你需要构造一个长度为m的数组b[1,2,...m],需要满足如下条件:

(1)b是a的子序列

(2)b[i]&b[i-1]!=0 (2<=i<=m)

问构造出b后,m的最大值是多少。

输入格式

 

输入文件共2行。第一行包括一个整数n。

第二行包括n个整数,第i个整数表示a[i]。

1<=n<=1e5,1<=a[i]<=1e9

 

输出格式

 

一个整数,表示m的最大值

 

输入/输出例子1

输入:

3

1 2 3

 

输出:

2

 

样例解释

 

位运算都考虑拆位!一位一位看!

做法一:
f[i]:以第i个数结尾满足的最长序列
记录lst数组,第i进制位是1属于的最近的a数组下标

https://www.luogu.com.cn/article/ncpi87q5

 

 

做法二:
逐步考虑每一位
对于每一位,二进制位数上是1的可以建一个图,例如

a的第3个进制位是1
b的第3个进制位是1
那么我们建 a->b 的有向边

图保证无环,我们找图的最长链就是答案(拓扑)

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;

int n, b[N], d[N], ans=0, dis[N];
vector<int> a[N];
queue<int> q;
void topsort()
{
	q.push(0);
	
	while (!q.empty())
	{
		int u=q.front();
		q.pop();
		
		for (int i=0; i<a[u].size(); i++)
		{
			int v=a[u][i];
			
			if (dis[v]<dis[u]+1) dis[v]=dis[u]+1;
			ans=max(ans, dis[v]);
			
			d[v]--;
			if (!d[v]) q.push(v);
		}
	}
}
int main()
{
	scanf("%d", &n);
	for (int i=1; i<=n; i++) scanf("%d", &b[i]);
	
	for (int k=0; k<=32; k++)
	{
		int last=0;
		for (int i=1; i<=n; i++)
			if (b[i]&(1<<k))
			{
				a[last].push_back(i);
				d[i]++;
				last=i;
			}
	}
		
	topsort();
	
	printf("%d", ans);
	return 0;
}

  


做法三:
覆盖

https://www.luogu.com.cn/article/w99xswjw

#include <bits/stdc++.h>
using namespace std;
const int N=50;

int n, a, f[N], ans=0;
int main()
{
	scanf("%d", &n);
	for (int i=1; i<=n; i++) 
	{
		int t=0, Max=0, cnt=0;
		scanf("%d", &a);
		
		t=a;
		while (t>0)
		{
			cnt++;
			if (t&1) Max=max(Max, f[cnt]);
			t>>=1;
		}
		
		cnt=0, t=a;
		while (t>0)
		{
			cnt++;
			if (t&1) f[cnt]=max(Max+1, f[cnt]);
			t>>=1;
		}
	}
	
	for (int i=1; i<=32; i++) ans=max(ans, f[i]);
	
	printf("%d", ans);
	return 0;
}

  

 

 

 

 

 

标签:cnt,int,luogu,www,com,最长
From: https://www.cnblogs.com/didiao233/p/18357778

相关文章

  • 最长的一帧学习(待补)
    文章目录一、osgViewer::ViewerBase::frame()1.osgViewer::View::init()2.osgViewer::Viewer::realize(),窗口和场景的“设置”工作part1GraphicsContextpart1.1通过阅读osgViewer::View::setUpViewInWindow()了解osg最基础的操作part2DisplaySettingspart3遍历......
  • Leetcode热题100-128.最长连续序列
    Leetcode热题100-128.最长连续序列1.题目描述2.解题思路3.代码实现1.题目描述128.最长连续序列2.解题思路使用哈希集合的思想:初始化一个unordered_set并将nums中所有元素放入集合中;遍历数组,依次判断当前元素是否为连续序列的开始,若是则求出当前连续序列......
  • leetcode 718. 最长重复子数组,leetcode 1143. 最长公共子序列
    leetcode718和leetcode1143两道十分相似的题,就不放题目了思路实际上区别就在于一个要求连续数组,另一个要求不连续的序列。二者的dp表达式和状态转移其实是不一致的,前者f[i][j]代表nums1以i结尾nums2以j结尾的最长子数组长度,后者代表nums1以i结尾nums2以j结尾的区间内存......
  • 最长上升子序列
    普通#include<iostream>usingnamespacestd;#include<algorithm>#include<cstring>constintN=5010;intn,f[N];inta[N];intmain(){ cin>>n; for(inti=1;i<=n;i++)cin>>a[i]; for(inti=1;i<=n;i++......
  • 代码随想录 day 47 回文子串 | 最长回文子序列
    回文子串回文子串解题思路dp数组的状态是判断以i结尾,j开始的字符串是否为回文,用bool类型存储,之后当i和j的字符串相等时,通过计算它们之间的距离和判断它们之间是否为回文串来进行递归。知识点回文,动态规划心得如果不看题解根本想不到怎么做最长回文子序列最长回文子序列......
  • L2-008 最长对称子串 C++
    对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定IsPAT&TAPsymmetric?,最长对称子串为sPAT&TAPs,于是你应该输出11。输入格式:输入在一行中给出长度不超过1000的非空字符串。输出格式:在一行中输出最长对称子串的长度。输入样例:IsPAT&TAPsymmetric?输出样......
  • 最长上升子序列(LIS)
    最长上升子序列(LIS)前情提要子串:连续的子序列:非连续,但相对序的抛出示例15239524等8个数a[8]前1个数构成的LIS:最长是1。子序列为:1前2个数构成的LIS:最长是2。子序列为:15前3个数构成的LIS:最长是2。子序列为:15或12(但我们只考虑12)前4个数构成的LI......
  • 最长最短单词【原创】
    最长最短单词描述输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一个连续的字母构成,空格和逗号都是单词间的间隔。试输出第1个最长的单词和第1个最短单词。输入一行句子。输出......
  • 【LeetCode:3. 无重复字符的最长子串 + 滑动窗口】
    ......
  • 代码随想录 day 44 最长公共子序列 | 不相交的线 | 最大子序和 | 判断子序列
    最长公共子序列最长公共子序列解题思路本题dp数组的含义是最长公共序列,而后同时遍历两个字符串,遇到相同的字母是公共子序列+1,否则取两个字符串的公共子序列中较长的一个。知识点动态规划,子序列心得没有想到比较两个字符串的公共子序列。我自己是遇到相同字母时将所有后续的......