[JSOI2009]火星藏宝图
XV.[JSOI2009]火星藏宝图
一个非常显然的结论:在最优方案中,路径上的任意两个点所构成的矩形内部一定不存在其它点。不然的化,在这个其它的点多停留一下一定不会更差。
因为。
但是,就算想到这个,我也得不出什么好的转移方式
考虑将所有岛屿按照行优先,如果行相同就按列优先进行排序。这样,对于任何一个岛,所有编号小于的且列比它小的岛都是可转移的。
而在所有列相同的岛中,行最大的那个一定是最优的。
因此我们可以针对每行维护一个列数最大的点(类似于桶),每次只需要遍历这些桶进行转移即可。
复杂度,卡卡就卡过去了。
代码:
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
int n,m,tri[1010],f[200100];
struct node{
int x,y,v;
friend bool operator <(const node &x,const node &y){
if(x.x!=y.x)return x.x<y.x;
return x.y<y.y;
}
}is[200100];
inline void read(int &x){
x=0;
char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
inline void print(int x){
if(x<0)putchar('-'),x=-x;
if(x<=9)putchar('0'+x);
else print(x/10),putchar('0'+x%10);
}
int main(){
read(n),read(m);
for(register int i=1;i<=n;i++)read(is[i].x),read(is[i].y),read(is[i].v);
sort(is+1,is+n+1);
tri[1]=1;
f[1]=is[1].v;
for(register int i=2;i<=n;i++){
f[i]=f[1]-(is[i].x-1)*(is[i].x-1)-(is[i].y-1)*(is[i].y-1);
for(register int j=1;j<=is[i].y;j++)if(tri[j])f[i]=max(f[i],f[tri[j]]-(is[i].x-is[tri[j]].x)*(is[i].x-is[tri[j]].x)-(is[i].y-is[tri[j]].y)*(is[i].y-is[tri[j]].y));
f[i]+=is[i].v;
tri[is[i].y]=i;
}
print(f[n]);
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,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?