CF559E Gerald and Path 题解
Gerald and Path
考虑将所有线段按照固定的那一端从小往大排序,并且对线段的端点离散化。
这之后,设
我们考虑,假设我们放了一根线段
于是我们现在考虑处理第
首先,其有可能在接下来(或者在
其次,考虑其向右摆。向右摆,就意味着最右位置一定是
则有
但是这也意味着,我们的线段
然后就考虑其向左摆了。向左摆,就意味着最右位置不一定是
首先,最右位是
然后,对于最右位不是
设所有
时间复杂度
代码:
#include<bits/stdc++.h>
using namespace std;
#define bs(x) lower_bound(v.begin(),v.end(),x)-v.begin()+1
const int N=110;
int n,m,f[N][N];
pair<int,int> p[N];
vector<int>v;
int L[N],P[N],R[N],res;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&p[i].first,&p[i].second);
v.push_back(p[i].first);
v.push_back(p[i].first-p[i].second);
v.push_back(p[i].first+p[i].second);
}
sort(p+1,p+n+1);
sort(v.begin(),v.end());
v.resize(m=unique(v.begin(),v.end())-v.begin());
for(int i=1;i<=n;i++){
L[i]=bs(p[i].first-p[i].second);
P[i]=bs(p[i].first);
R[i]=bs(p[i].first+p[i].second);
}
for(int i=1;i<=n;i++){
memcpy(f[i],f[i-1],sizeof(f[i]));
for(int j=P[i];j<=R[i];j++) f[i][j]=max(f[i][j],f[i-1][P[i]]+v[j-1]-v[P[i]-1]);
for(int j=i;j;j--){
int Rmax=(j==i?P[j]:R[j]);
if(Rmax<P[i])continue;
int Lmin=(j==i?L[j]:P[j]);
for(int k=j+1;k<=i;k++) Lmin=min(Lmin,L[k]);
for(int k=Lmin;k<=Rmax;k++) f[i][k]=max(f[i][k],f[j-1][Lmin]+v[k-1]-v[Lmin-1]);
}
for(int j=1;j<=m;j++) f[i][j]=max(f[i][j],f[i][j-1]);
}
for(int i=1;i<=m;i++) res=max(res,f[n][i]);
printf("%d\n",res);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】