题目链接
题意简述
给定一个长度为 \(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;
}
标签:dp1,long,200010,CF1272D,序列,杂题,dp,define
From: https://www.cnblogs.com/wangmarui/p/17896396.html