zoukankan      html  css  js  c++  java
  • [JSOI2009]火星藏宝图

    XV.[JSOI2009]火星藏宝图

    一个非常显然的结论:在最优方案中,路径上的任意两个点所构成的矩形内部一定不存在其它点。不然的化,在这个其它的点多停留一下一定不会更差。

    因为\(a^2+b^2<(a+b)^2\)

    但是,就算想到这个,我也得不出什么好的转移方式

    考虑将所有岛屿按照行优先,如果行相同就按列优先进行排序。这样,对于任何一个岛\(i\),所有编号小于\(i\)的且列比它小的岛都是可转移的。

    而在所有列相同的岛中,行最大的那个一定是最优的。

    因此我们可以针对每行维护一个列数最大的点(类似于桶),每次只需要遍历这些桶进行转移即可。

    复杂度\(O(nm)\),卡卡就卡过去了。

    代码:

    #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;
    }
    

  • 相关阅读:
    hdu 2569
    hdu 2571
    hdu 4540
    Linux:远程到linux的图形界面
    Windows:文件服务器,访问进去不能查看到完整的文件
    Linux:去除认证,加速 SSH登录
    Linux:永久修改网卡的MAC地址
    Loadrunner:LR提交JSON格式的POST请求
    Linux: vi 编辑器中文乱码
    自动化测试相关:Android SDK无法下载问题,不FQ的解决办法
  • 原文地址:https://www.cnblogs.com/Troverld/p/14596900.html
Copyright © 2011-2022 走看看