【BZOJ1560】[JSOI2009]火星藏宝图(贪心,动态规划)

【BZOJ1560】[JSOI2009]火星藏宝图(贪心,动态规划)

题面

BZOJ
洛谷

题解

既然所有的位置的权值都大于\(0\),那么就可以直接贪心,按照行为第一关键字,列为第二关键字,来转移。显然如果一个点可以从某一列的一些位置转移过来,那么显然从行最大的那个位置转移过来是最优的,这个随便推一下就知道了。
这样子时间复杂度\(O(nm)\),然后就过了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 200200
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Node{int x,y,v;}p[MAX];
int n,m,a[1010],f[MAX];
bool operator<(Node a,Node b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
int Sqr(int x){return x*x;}
int Trans(int j,int i){return f[j]-Sqr(p[j].x-p[i].x)-Sqr(p[j].y-p[i].y);}
int main()
{
	n=read();m=read();p[0].x=p[0].y=1;
	for(int i=1;i<=n;++i)p[i].x=read(),p[i].y=read(),p[i].v=read();
	sort(&p[1],&p[n+1]);memset(f,-63,sizeof(f));f[0]=0;
	for(int i=1;i<=n;++i)
	{
		for(int j=0;j<=p[i].y;++j)
			f[i]=max(f[i],Trans(a[j],i)+p[i].v);
		a[p[i].y]=i;
	}
	printf("%d\n",f[n]);
	return 0;
}
posted @ 2018-10-15 16:54  小蒟蒻yyb  阅读(313)  评论(0编辑  收藏  举报