这里是\(sb\)的\(O(nm)\)做法

上一篇题解里写的\(O(nm)\)做法并没有看懂,我真是好菜啊

这是一个用了斜率优化,但是复杂度仍然是\(O(nm)\)的做法

我们还是先写出简单的\(dp\)方程

\(dp[i]\)表示到达第\(i\)个点的时候的最大收益

于是就有

\[dp[i]=max(dp[j]+w[i]-(a[i].x-a[j].x)^2-(a[i].y-a[j].y)^2)
\]

显然暴力转移是\(O(n^2)\)的

我们发现\(m\)非常的小,于是我们可以考虑一下把\(n\)优化成\(m\)

我们先将整个矩阵破坏成一条链,之后给每一个点一个新编号,对于原来的点\((x,y)\),新编号就是\((x-1)*m+y\),我们按照新编号给点从小到大排序

于是我们按照这个样子来进行\(dp\)的话就可以方便的找到某个点右上的所有点了

我们可以开上\(m\)个队列,第\(i\)个队列\(q[i]\)存储的是\(i\)这一列上面所有的点

于是我们更新一个点的时候只需要去枚举它之前的所有列对应的队列就好了

之后我们就可以来斜率优化了

由于我们枚举的是列数,那么\((a[i].y-a[j].y)^2\)就固定了,为了方便化柿子,我们设\(c=(a[i].y-a[j].y)^2\)

于是就有

\[dp[i]=dp[j]+w[i]-c-(a[i].x-a[j].x)^2
\]

\[dp[i]=dp[j]+w[i]-c-a[i].x^2-a[j].x^2+2*a[i].x*a[j].x
\]

\[-2*a[i].x*a[j].x+dp[i]+c-w[i]=dp[j]-a[j].x^2
\]

这个柿子显然可以列率优化,截距为\(dp[i]+c-w[i]\),斜率为\(-2*a[i].x\)由于斜率单减,我们要求最大化截距,所以维护一个上凸壳就好了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define re register
#define maxn 1005
#define max(a,b) ((a)>(b)?(a):(b))
inline int read()
{
char c=getchar();
int x=0,r=1;
while(c<'0'||c>'9')
{
if(c=='-') r=-1;
c=getchar();
}
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
struct Point
{
int x,y,rk;
int w;
}a[200005];
int dp[200005];
int q[maxn][maxn],head[maxn],tail[maxn];
inline int cmp(Point K,Point M)
{
return K.rk<M.rk;
}
#define X(i) (a[i].x)
#define Y(i) (dp[i]-a[i].x*a[i].x)
inline double K(int i,int j)
{
return double(Y(i)-Y(j))/double(X(i)-X(j));
}
int n,m;
int main()
{
n=read(),m=read();
for(re int i=1;i<=n;i++)
{
a[i].x=read(),a[i].y=read(),a[i].w=read();
a[i].rk=(a[i].x-1)*m+a[i].y;
}
std::sort(a+1,a+n+1,cmp);
memset(dp,-20,sizeof(dp));
dp[1]=a[1].w;
q[1][++tail[1]]=1;
for(re int i=2;i<=n;i++)
{
int T=a[i].y;
for(re int j=1;j<=T;j++)
{
int c=(T-j)*(T-j);
while(head[j]<tail[j]&&-2*a[i].x<K(q[j][head[j]],q[j][head[j]+1])) head[j]++;
dp[i]=max(dp[i],dp[q[j][head[j]]]+a[i].w-c-(a[q[j][head[j]]].x-a[i].x)*(a[q[j][head[j]]].x-a[i].x));
}
while(head[T]<tail[T]&&K(i,q[T][tail[T]-1])>K(q[T][tail[T]],q[T][tail[T]-1])) tail[T]--;
q[T][++tail[T]]=i;
}
std::cout<<dp[n];
return 0;
}

【[JSOI2009]火星藏宝图】的更多相关文章

  1. bzoj 1560 [JSOI2009]火星藏宝图(DP)

    1560: [JSOI2009]火星藏宝图 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 647  Solved: 309[Submit][Status ...

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

    [BZOJ1560][JSOI2009]火星藏宝图(贪心,动态规划) 题面 BZOJ 洛谷 题解 既然所有的位置的权值都大于\(0\),那么就可以直接贪心,按照行为第一关键字,列为第二关键字,来转移. ...

  3. bzoj1560:[JSOI2009]火星藏宝图(斜率优化)

    题目描述 在火星游玩多日,jyy偶然地发现了一张藏宝图.根据藏宝图上说法,宝藏被埋藏在一个巨大的湖里的N个岛上(2<=N<=200,000).为了方便描述,地图把整个湖划分成M行M列(1& ...

  4. bzoj1560: [JSOI2009]火星藏宝图

    考虑到一个性质,A到B的距离一定不小于A到C再到B的距离,因为能够到达这三个点不可能构成锐角三角形 对于当前点的更新只需要找那些无法经过其它点再到当前点的点,相当于是一个y坐标单调减的上凸包,随便维护 ...

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

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

  6. 【BZOJ1560】【JSOI2009】火星藏宝图 [DP]

    火星藏宝图 Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description Input Output Samp ...

  7. BZOJ 1560 火星藏宝图(DP)

    思路:发现如果从A能到B,B能到C,那么一定A能到C,且根据不等式:A^2+B^2<=(A+B)^2,而且权值没有负数,因此经过B比不经过B要优,因此,我们从左上到右下做,每一列,我们只记录之前 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. dp专练

    dp练习. codevs 1048 石子归并 区间dp #include<cstdio> #include<algorithm> #include<cstring> ...

随机推荐

  1. unity TileMap 简述

    主要工具 说明 更多说明 Sprite 精灵,纹理的容器. 大型纹理图集可以转为精灵图集(Sprite Sheet). Tile 瓦片,包含一个精灵,以及两个属性,颜色和碰撞体类型.   Tilema ...

  2. webpack工具、Vue、react模块化

    一.为什么要有webpack print('hello,world') fsdl fdsf title2 title3 引用 斜体字 加粗 有序列表1 有序列表2 无序列表1 无序列表2 行内code ...

  3. 项目中遇到的问题——jsp:include

    昨晚记错了,项目中用的是这个<jsp:attribute>,不过没关系,都差不多!原理是传参数 具体用法: 假设有两个tag文件  aaa 和 bbb aaa有两个属性:name  age ...

  4. java poi处理新版xlsx后缀的excel

    jar包下载地址http://poi.apache.org/download.html#POI-3.17,我把下载文件中的所有jar包都导入项目中才能跑 参考以下博客 https://www.cnbl ...

  5. docker启动容器报错:IPv4 forwarding is disabled. Networking will not work

    报这个错误会导致宿主机以外的pc 访问不了容器 按照网上的解决办法: 在/usr/lib/sysctl.d/00-system.conf文件后加net.ipv4.ip_forward=1 即可 然后重 ...

  6. 第二章.JSP/Servlet及相关技术详解

    JSP的4种基本语法: 1.JSP注释: <%-- JSP注释部分 --%> 2.JSP声明: <%! //声明一个整型变量 public int count; //声明一个方法 p ...

  7. Chromium base库分割字符串SplitString

    前一段时间在工作过程中遇到一个场景需要将http response中的request header中的cookie字段取出并进行解析,但是手头没有解析cookie的工具类,同时cookie的表现就是个 ...

  8. WinFrom饼形图

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. 从JSON中读取数据追加到HTML中

    本文来自https://www.jianshu.com/p/04127d74d88c,并非本人原创,只是作为自己学习使用的资料,如有浏览者请点击地址自行到原作者页面浏览 有时候我们需要将json数据直 ...

  10. 洛谷 P3391 文艺平衡树

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 --b ...