[luogu4056 JSOI2009] 火星藏宝图 (贪心 dp)

传送门

Solution

一个显然的贪心:选的点数越多越好。这个随便推推就知道了。
那么我们就贪心的从一列上挑最靠下的转移
直接转移不斜率优化复杂度\(O(nm)\),吸一口O2过了。。。

Code

//By Menteur_Hxy
#pragma GCC optimize(2)
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
typedef long long LL;

char buf[1<<21],*p1,*p2;
inline int read() {
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}

const int MAXN=2e5+5,MAXM=1010,INF=0x3f3f3f3f;
int n,m;
int pos[MAXM],f[MAXM];

struct P{int x,y,v;}p[MAXN];

inline bool cmp(P a,P b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
inline int F(int i,int j) {return f[j]-(p[i].y-j)*(p[i].y-j)-(p[i].x-pos[j])*(p[i].x-pos[j]);}

int main() {
	n=read(),m=read();
	Fo(i,1,n) p[i].x=read(),p[i].y=read(),p[i].v=read();
	sort(p+1,p+1+n,cmp); pos[1]=1; f[1]=p[1].v;
	Fo(i,2,n) {
		int tmp=-INF;
		Fo(j,1,p[i].y) if(pos[j]) tmp=max(tmp,F(i,j));
		pos[p[i].y]=p[i].x; f[p[i].y]=tmp+p[i].v;
	}
	printf("%d",f[m]);
	return 0;
}
posted @ 2018-10-19 20:49  Menteur_hxy  阅读(134)  评论(0编辑  收藏  举报