关于dp的优化之前做过一些简单的利用优先队列或者单调队列维护一个值就ok了,但有时候给出的方程很难直接用单调队列维护,需要转化一下思路。

这种优化方式利用数形结合,根据比较斜率来抛去一些非最优解,能将方程优化到线性,但对于一些更难得题目就需要一些数据结构维护,我暂时没接触过。

先用一道简单的题目来入手,hdu 3507 http://acm.hdu.edu.cn/showproblem.php?pid=3507

Print Article

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 13750    Accepted Submission(s): 4247

Problem Description
Zero
has an old printer that doesn't work well sometimes. As it is antique,
he still like to use it to print articles. But it is too old to work for
a long time and it will certainly wear and tear, so Zero use a cost to
evaluate this degree.
One day Zero want to print an article which has
N words, and each word i has a cost Ci to be printed. Also, Zero know
that print k words in one line will cost

M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.
 
Input
There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.
 
Output
A single number, meaning the mininum cost to print the article.
 
Sample Input
5 5
5
9
5
7
5
 
Sample Output
230
      一个显然的方程就是 f[i]=MIN{ f[j]+M+(sum[j]-sum[i])^2  },复杂度O(N^2) 显然也会T。令 k<j<i ,不妨假设如果j点作为决策点比k更优的话需要满足什么条件,显然是
f[j]+(sum[j]-sum[i])^2 < f[k]+(sum[k]-sum[i])^2   --->    f[j]+sum[j]^2-(f[k]+sum[k]^2) < 2*sum[i]*(sum[j]-sum[k] )  -------> 即  g(k,j)= ( (f[j]+sum[j]^2)-(f[k]+sum[k]^2) ) / (sum[j]-sum[k]) < 2*sum[i];
由此我们得到了一个判别式g(k,j),如果 k<j<i&&g(k,j)<2*sum[i]就足以说明j优于k。
    令yj=f[j]+sum[j]^2, x[j]=sum[j],  那么简写为 (yj-yk)/(xj-xk)<2*sum[i], 像极了斜率的推导公式。从这个式子中我们得到一些性质,由于sum[i]是显然递增的,所以当前状态下如果j优于k那么
在后面的状态中j始终会优于k所以我们可以抛去k  -> 1.if(g(k,j)<=2*sum[i]) pop(k)               //ps.相等时二者等价所以可以删去        2.if(g(k,j)>=g(j,i)) pop(j)  关于这个的正确性在于
如果g(j,i)<=2*sum,显然i优于等于j; 如果g(j,i)>2*sum,那么g(k,j)>2*sum ,所以k优于j,综上 j是无用点,所以可以抛去。
   有一个重要的性质在于: 所有最优决策点都在平面点集的凸包上。
令ai=-2*sum[i],xj=sum[j],yj=f[j]+sum[j],  那么min{p}=ax+y -->  y=p-ax, 当在y轴上的截距最小时有最优解p,相当于把每个sum[i]和对应的最优解当作了一个点。
 
 
 

将小于j的点画在平面直角坐标系上,一如线性规划,把这条斜线自下往上平移时遇到的第一个点,即能使目前状态有最小值的点。于是我们需要维护一个下凸壳,把那些肯定不会贡献的点删掉。

   根据上面的推倒代码就很好写了。

 #include<bits/stdc++.h>
using namespace std;
#define qz q.size()
int f[];
int sum[];
deque<int>q;
int dy(int i,int j){return f[j]-f[i]+sum[j]*sum[j]-sum[i]*sum[i];}
int dx(int i,int j){return sum[j]-sum[i];}
int main()
{
int N,M,i;
while(scanf("%d%d",&N,&M)==){
q.clear();
q.push_back();
for(i=;i<=N;++i)
{
scanf("%d",sum+i);
sum[i]+=sum[i-];
while(qz>&&dy(q[],q[])<=*dx(q[],q[])*sum[i]) q.pop_front();
f[i]=f[q.front()]+M+(sum[i]-sum[q.front()])*(sum[i]-sum[q.front()]);
while(qz>&&dy(q[qz-],i)*dx(q[qz-],q[qz-])<=dy(q[qz-],q[qz-])*dx(q[qz-],i))q.pop_back();
q.push_back(i);
}
printf("%d\n",f[N]);
}
return ;
}
和上面的做法类似。
 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define qz q.size()
LL f[];
LL sum[];
int N,L;
deque<int>q;
LL dy(int i,int j,int a){
return (f[j]+(sum[j]-(a-j+-L))*(sum[j]-(a-j+-L)))-(f[i]+(sum[i]-(a-i+-L))*(sum[i]-(a-i+-L)));
}
LL dx(int i,int j,int a){return (sum[j]-(a-j+-L))-(sum[i]-(a-i+-L));}
int main()
{
int i;
while(scanf("%d%d",&N,&L)==){
q.clear();
q.push_back();
for(i=;i<=N;++i)
{
scanf("%d",sum+i);
sum[i]+=sum[i-];
}
for(i=;i<=N;++i)
{
while(qz>&&dy(q[],q[],i)<=*dx(q[],q[],i)*sum[i]) q.pop_front();
f[i]=f[q[]]+(sum[i]-sum[q[]]+i-q[]--L)*(sum[i]-sum[q[]]+i-q[]--L);
while(qz>&&dy(q[qz-],i,i)*dx(q[qz-],q[qz-],i)<=dy(q[qz-],q[qz-],i)*dx(q[qz-],i,i))q.pop_back();
q.push_back(i);
}
printf("%lld\n",f[N]);
}
return ;
}

1D/1D优化dp之利用决策点的凸性优化的更多相关文章

  1. DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)

    前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下.运算一般都要满足可减性. 比较naive就不展开了. 题目 [Todo]洛谷P2513 [HAOI2009]逆序对数列 [D ...

  2. 『土地征用 Land Acquisition 斜率优化DP』

    斜率优化DP的综合运用,对斜率优化的新理解. 详细介绍见『玩具装箱TOY 斜率优化DP』 土地征用 Land Acquisition(USACO08MAR) Description Farmer Jo ...

  3. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  4. 关于单调性优化DP算法的理解

    Part1-二分栈优化DP 引入 二分栈主要用来优化满足决策单调性的DP转移式. 即我们设\(P[i]\)为\(i\)的决策点位置,那么\(P[i]\)满足单调递增的性质的DP. 由于在这种DP中,满 ...

  5. 算法优化》关于1D*1D的DP的优化

    关于这一主题的DP问题的优化方法,我以前写过一篇博客与其有关,是关于对递推形DP的前缀和优化,那么这种优化方法就不再赘述了. 什么叫1D*1D的DP捏,就是一共有N种状态,而每种状态都要N种决策,这就 ...

  6. CF868F Yet Another Minimization Problem 分治决策单调性优化DP

    题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...

  7. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  8. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  9. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

随机推荐

  1. Linux中的系统挂载文件/etc/fstab

    [root@localhost ~]# cat /etc/fstab ## /etc/fstab# Created by anaconda on Wed Oct 5 15:21:46 2016## A ...

  2. 002-IP地址及分类以及子网掩码

    一.概述 IP地址是一个4段2进制码组成的,每一段二进制码有8位,共32位二进制数.占用4个字节. IP地址是指互联网协议地址(Internet Protocol Address,又译为网际协议地址) ...

  3. 001-maven下载jar后缀为lastUpdated问题

    问题简述 Maven在下载仓库中找不到相应资源时,网络中断等,会生成一个.lastUpdated为后缀的文件.如果这个文件存在,那么即使换一个有资源的仓库后,Maven依然不会去下载新资源. 解决方案 ...

  4. F110 BADI增强

    F110*JOB*&------------------------------------------------------------- F110 BADI FI_BSTM_MC_EXI ...

  5. Verilog HDL设计规范及经验谈(转载)

    1. 规范很重要      工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的.逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现 ...

  6. celery的安装和使用

    celery是python开发的分布式任务调度模块,接口简单,开发容易,五分钟就写出一个异步发送邮件的服务,celery本身不含消息服务,它使用第三方消息服务来传递任务,目前,celery支持的消息服 ...

  7. Python基础(10)_内置函数、匿名函数、递归

    一.内置函数 1.数学运算类 abs:求数值的绝对值 divmod:返回两个数值的商和余数,可用于计算页面数 >>> divmod(5,2) (2, 1) max:返回可迭代对象中的 ...

  8. PAT 天梯赛 L1-032. Left-pad 【字符串】

    题目链接 https://www.patest.cn/contests/gplt/L1-032 思路 要分两种情况处理 ①字符串长度 <= 填充长度 就在字符串前面输出(填充长度 - 字符串长度 ...

  9. [SCOI2003]蜘蛛难题

    题目 对于当年来说似乎是神题?? 做法 对于联通注水来说,我们考虑把所有能平分到水的桶同时加高度,然后暴力判断 My complete code copy来的代码 #include <cstdi ...

  10. Docker 跨主机网络

    Docker提供两种原生的跨主机网络: Overlay  和  Macvlan libnetwork & CNM libnetwork 是 docker 容器网络库,最核心的内容是其定义的 C ...