Description
Input
Output
Sample Input
4 10
1 1 20
10 10 10
3 5 60
5 3 30
1 1 20
10 10 10
3 5 60
5 3 30
Sample Output
-4
HINT
题解:
首先数据范围虽然不全,但是裸dp肯定会T.
根据完全平方公式 (a+b)^2>=a^2+b^2;
所以我们可以发现,从A到B再到C,一定比从A直接到C要优。
所以对于每一列其实只有当前最靠下的点有用。
我们维护一下这些点,每次只用这些点去更新即可。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 200010
using namespace std;
struct use{int x,y,v;}a[N];
bool cmp(use a,use b){if (a.x==b.x) return a.y<b.y;else return a.x<b.x;}
int pos[N],n,m;
long long f[N];
int main(){
scanf("%d%d",&n,&m);n+=2;
a[1].x=a[1].y=1;a[2].x=a[2].y=m;
for (int i=3;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);
sort(a+2,a+n+1,cmp);
pos[1]=1;
for (int i=2;i<=n;i++){
long long t=-999999999999999;
for (int j=1;j<=a[i].y;j++)
if (pos[j]) t=max(t,f[j]-(a[i].y-j)*(a[i].y-j)-(a[i].x-pos[j])*(a[i].x-pos[j]));
pos[a[i].y]=a[i].x;f[a[i].y]=t+a[i].v;
}
cout<<f[m]<<endl;
}