CF559E Gerald and Path
CXXIX.CF559E Gerald and Path
考虑将所有线段按照固定的那一端从小往大排序,并且对线段的端点离散化。
这之后,设 表示当前处理到线段 ,且所有线段中最右的那根的右端点不右于位置 (即可以在 左面或与 重合)时的最优答案。
我们考虑,假设我们放了一根线段 。因为不知道将来会放什么东西把它盖掉一部分,所以我们干脆在放线段 时,同时也放下线段 ,这样就不用担心被盖掉等讨论了。
于是我们现在考虑处理第 根线段。设其向左是 ,向右是 。
首先,其有可能在接下来(或者在 之前就已经)被完全覆盖掉。于是一开始就有 。
其次,考虑其向右摆。向右摆,就意味着最右位置一定是 ——若最右位不是 ,则一定在 之前还有一条向右摆的线段 满足 。但是因为我们已经按照 递增排序了,故必有 ,即 被完全覆盖,我们已经在上面说过了。
则有 ——因为我们已经令 表示“不右于”的最优值,所以就不用费尽心思枚举 时的最右位置了。同时,也不用担心重叠问题,因为按照我们上述讨论,为了避免重叠,我们直接将线段 看作了所有 。
但是这也意味着,我们的线段 也要被看作是所有的 。于是我们枚举 ,则有 。
然后就考虑其向左摆了。向左摆,就意味着最右位置不一定是 ——因为完全可以存在一条 ,满足 ,即两者无交。
首先,最右位是 的就可以跟之前一样类似地转移,不在话下。
然后,对于最右位不是 的,我们枚举一个 ,表示最右位是 对应的 (明显这里上述 应被满足)。则所有 都应该向左摆,因为若其向右摆,要么右端点在 左边或与 重合,被完全包含;要么右端点在 右边,则 就不是最右位了。
设所有 的东西中,最左的那个是 ,则整个 中所有线段,加一块可以变成一个 的大线段,且该线段是最右的。于是此处就可以跟前面一样,枚举一个 进行转移了。
时间复杂度 ,因为枚举了 三个元素。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,f[110][310];
pair<int,int>p[110];
vector<int>v;
int L[110],P[110],R[110],res;
#define bs(x) lower_bound(v.begin(),v.end(),x)-v.begin()+1
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 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?