BZOJ 1560 火星藏宝图(DP)

思路:发现如果从A能到B,B能到C,那么一定A能到C,且根据不等式:A^2+B^2<=(A+B)^2,而且权值没有负数,因此经过B比不经过B要优,因此,我们从左上到右下做,每一列,我们只记录之前做过的最下面的那个位置的信息,然后从这个位置的前几列里面寻找最优。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define ll long long
 7 #define inf 999999999
 8 struct Point{
 9     int x,y,w;
10     Point(){}
11     Point(int x0,int y0):x(x0),y(y0){}
12 }a[200005];
13 int n,m,b[200005],c[200005];
14 int read(){
15     int t=0,f=1;char ch=getchar();
16     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
17     while (ch<='9'&&ch>='0'){t=t*10+ch-'0';ch=getchar();}
18     return t*f;
19 }
20 bool cmp(Point p1,Point p2){
21     if (p1.x!=p2.x) return p1.x<p2.x;
22     return p1.y<p2.y;
23 }
24 int sqr(int x){
25     return x*x;
26 }
27 int dis(Point p1,Point p2){
28     return sqr(p1.x-p2.x)+sqr(p1.y-p2.y);
29 }
30 int main(){
31     n=read();m=read();
32     for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].w=read();
33     std::sort(a+1,a+1+n,cmp);
34     for (int i=1;i<=m;i++) b[i]=-inf;
35     b[1]=a[1].w;
36     c[1]=1;
37     int tmp;
38     for (int i=2;i<=n;i++){
39         int x=a[i].x,y=a[i].y,w=a[i].w;
40         tmp=-inf;
41         for (int j=1;j<=y;j++)
42          tmp=std::max(tmp,b[j]-dis(Point(x,y),Point(c[j],j)));
43         tmp+=w;
44         b[y]=tmp;c[y]=x;
45     }
46     printf("%d\n",tmp);
47 }

 

posted @ 2016-06-11 20:45  GFY  阅读(235)  评论(0编辑  收藏  举报