「杂题乱刷」CF1272D

题目链接

CF1272D Remove One Element

题意简述

给定一个长度为 \(n\) 的序列,你需要求出至多删除一个数后的这个序列的最长上升子串。

解题思路

首先我们可以想一下这题的弱化版,给定一个长度为 \(n\) 的序列,你需要求出至多删除一个数后的这个序列的最长上升子序列。

这题我们可以设 \(dp_i\) 为到位置 \(i\),所能得到的最长子序列,然后代码就很容易实现了。

参考代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[5010],dp[5010],ans;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define QwQ return 0;
int main()
{
	IOS;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i],dp[i]=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=i-1;j>=1;j--)
			if(a[i]>a[j])
				dp[i]=max(dp[j]+1,dp[i]);
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	QwQ;
}

然后我们将这题加强一下,改为给定一个长度为 \(n\) 的序列,你需要求出这个序列的最长上升子序列。

这时我们维护 \(dp1_i\) 表示到第 \(i\) 个数可以达到的最长子串(从 \(1\) 开始),维护 \(dp2_i\) 表示到第 \(i\) 个数可以达到的最长子串(从 \(n\) 开始),这样维护也是比较轻松的。

参考代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[200010],dp1[200010],dp2[200010],ans;
#define map unordered_map
#define forl(i,a,b) for(register long long i=a;i<=b;i++)
#define forr(i,a,b) for(register long long i=a;i>=b;i--)
#define lc(x) x<<1
#define rc(x) x<<1|1
#define lowbit(x) x&-x
#define pb push_back
#define pf push_front
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
int main()
{
	IOS;
	cin>>n;
	forl(i,1,n)
		cin>>a[i];
	forl(i,1,n)
	{
		if(a[i]>a[i-1])
			dp1[i]=dp1[i-1]+1;
		else
			dp1[i]=1;
	}
	forr(i,n,1)
	{
		if(a[i]<a[i+1])
			dp2[i]=dp2[i+1]+1;
		else
			dp2[i]=1;
	}
	forl(i,1,n)
	{
		ans=max({ans,dp1[i],dp2[i]});
		if(a[i]<a[i+1])	
			ans=max(ans,dp1[i]+dp2[i+1]);
	}
	cout<<ans;
	QwQ;
}

然后就是此题了,相信只要看懂上面的内容,应该都可以写出来的,我们直接多考虑一个不考虑中间的数的情况即可。

参考代码

#include<bits/stdc++.h>
using namespace std;
long long n,a[200010],dp1[200010],dp2[200010],ans;
#define map unordered_map
#define forl(i,a,b) for(register long long i=a;i<=b;i++)
#define forr(i,a,b) for(register long long i=a;i>=b;i--)
#define lc(x) x<<1
#define rc(x) x<<1|1
#define lowbit(x) x&-x
#define pb push_back
#define pf push_front
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
int main()
{
	IOS;
	cin>>n;
	forl(i,1,n)
		cin>>a[i];
	forl(i,1,n)
	{
		if(a[i]>a[i-1])
			dp1[i]=dp1[i-1]+1;
		else
			dp1[i]=1;
	}
	forr(i,n,1)
	{
		if(a[i]<a[i+1])
			dp2[i]=dp2[i+1]+1;
		else
			dp2[i]=1;
	}
	forl(i,1,n)
	{
		ans=max({ans,dp1[i],dp2[i]});
		if(a[i]<a[i+2])	
			ans=max(ans,dp1[i]+dp2[i+2]);
	}
	cout<<ans;
	QwQ;
}
posted @ 2023-12-12 11:24  wangmarui  阅读(4)  评论(0编辑  收藏  举报