BZOJ 1560 火星藏宝图(DP)

Posted GFY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于BZOJ 1560 火星藏宝图(DP)的主要内容,如果未能解决你的问题,请参考以下文章

[JSOI2009]火星藏宝图

计蒜客 藏宝图

藏宝图

藏宝图

藏宝图题解

P3959 宝藏 状压dp