dp优化-四边形不等式(模板题:合并石子)
学习博客:https://blog.csdn.net/noiau/article/details/72514812
看了好久,这里整理一下证明
方程形式:dp(i,j)=min(dp(i,k)+dp(k+1,j))+cost(i,j) O(n^3)
四边形不等式:将其优化为O(n^2)
1.四边形不等式
a<b<=c<d
f(a,c)+f(b,d)<=f(b,c)+f(a,d)交叉小于包含
则对于i<i+1<=j<j+1
f(i,j)+f(i+1,j+1)<=f(i+1,j)+f(i,j+1)
f(i,j)-f(i+1,j)<=f(i,j+1)-f(i+1,j+1)
令g(j)=f(i,j)-f(i+1,j),则g(j)递增
2.若cost(i,j)有凸性,则dp(i,j)也有凸性
只需要证明对任意i<i+1<=j<j+1,有dp(i,j)+dp(i+1,j)<=dp(i+1,j)+dp(i,j+1)
设dp(i+1,j)取最优解的k=x,dp(i,j+1)取最优解的k=y
即要证:dp(i,j)+dp(i+1,j)<=dp(i,y)+dp(y+1,j+1)+dp(i+1,x)+dp(x+1,j)+cost(i,j+1)+cost(i+1,j)(1)
令A=dp(i,y)+dp(y+1,j+1)+dp(i+1,x)+dp(x+1,j);
由于dp(i,j)的最优解不一定为k=x,则dp(i,j)<=dp(i,x)+dp(x+1,y)+cost(i,j)
同理由于dp(i+1,j)的最优解不一定为k=y,则dp(i+1,j)<=dp(i+1,y)+dp(y+1,j)+cost(i+1,j)
(1)式可化为:
dp(i,j)+dp(i+1,j)<=A+cost(i,j)+cost(i+1,j)<=A+cost(i,j+1)+cost(i+1,j)
由cost的凸性可知成立,故dp(i,j)也有凸性
3.证明决策的单调性
设s(i,j)表示dp(i,j)最优时的k值
要证:s(i,j-1)<=s(i,j)<=s(i+1,j)
先证s(i,j-1)<=s(i,j):
设y=s(i,j-1),对任意x满足x<=y<j-1<j,有x+1<=y+1<=j-1<j
由四边形不等式:dp(x+1,j-1)+dp(y+1,j)<=dp(x+1,j)+dp(y+1,j-1)
令A=dp(i,x)+cost(i,j-1)+dp(i,y)+cost(i,j)
两边同时加上A
化简得到:dp(i,j-1)(k=x时的值)+dp(i,j)(k=y)<=dp(i,j)(k=x)+dp(i,j-1)(k=y)
移项:dp(i,j-1)(k=x)-dp(i,j-1)(k=y)<=dp(i,j)(k=x)-dp(i,j)(k=y)
由于k=y时dp(i,j-1)取最小值,则左边>=0,即dp(i,j)(k=x)>=dp(i,j)(k=y)
也就是说,对于dp(i,j),任意一个k=x<y都不如k=y优。
故s(i,j-1)<=s(i,j)
另一边同理(不证了)
那么关键就在于枚举k的部分
//s(i,j-1)<=s(i,j)<=s(i+1,j)
for(int i=n;i>=;i--)
(int j=i+;j<=n;j++)
{
int d=INF,id=;
for(int k=s[i][j-];k<=s[i+][j];k++)
{
if(d>dp[i][k]+dp[k+][j]+sum[j]-sum[i-])
{
d=dp[i][k]+dp[k][j]+sum[j]-sum[i-];
id=k;
}
}
dp[i][j]=d;
s[i][j]=id;
}
总复杂度O(n^2)
补充一个证明
来源为https://www.cnblogs.com/mlystdcall/p/6525962.html,我稍微加了一点点
对于固定的区间长度len,有
dp[i][i+len]的决策范围为s[i][i+len-1]至s[i+1][i+len]
dp[i+1][i+len+1]的决策范围为s[i+1][i+len]至s[i+2][i+len+1]
dp[i+2][i+len+2]的决策范围为s[i+2][i+len+1]至s[i+3][i+len+2]
如此脑补下去,我们发现,对于固定的区间长度len,总共的决策只有O(n)个!因为一共有O(n)个不同的区间长度len,所以算法的总复杂度就是O(n^2)!
模板题:合并石子
现在有n堆石子,要将石子按一定顺序地合成一堆,规定如下,每次只能移动相邻的两堆石子,合并费用为新和成一堆石子的数量,求把n堆石子全部合并到一起所花的最少或者最大花费
很容易想到这样一个dp转移
dp[i][j]=min{dp[i][k]+dp[k+1][j]}+cost[i][j]
震惊!这不就是之前所讲的模型嘛?原来之前O(n^3)方的合并石子问题还可以优化(我太弱了)
首先明确一点,cost[i][j]表示把第i堆到第j堆的石子和到一起的最后一步的代价,显然,之前无论怎么合并,最后一步的代价都是一样的,所以我们可以先预处理出这个cost数组,他等于cnt[j]-cnt[i-1],其中cnt数组是前缀和
---------------------
作者:NOIAu
来源:CSDN
原文:https://blog.csdn.net/noiau/article/details/72514812
版权声明:本文为博主原创文章,转载请附上博文链接!
分析题目:
只要证明cost(i,j)满足凸性。g(j)=cost(i,j)-cost(i+1,j)=sum(j)-sum(i-1)-sum(j)+sum(i)=sum(i)-sum(i-1)与j无关,满足(此时为等于)。
我的模板:
#include<bits/stdc++.h>
using namespace std; const int N=,INF=(int)1e9;
int dp[N][N],s[N][N],sum[N]; int main()
{
//freopen("a.in","r",stdin);
int n;
scanf("%d",&n);
sum[]=;
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
sum[i]=sum[i-]+x;
}
for(int i=;i<=n;i++) dp[i][i]=,s[i][i]=i;
//s(i,j-1)<=s(i,j)<=s(i+1,j)
for(int i=n;i>=;i--)
(int j=i+;j<=n;j++)
{
int d=INF,id=;
for(int k=s[i][j-];k<=s[i+][j];k++)
{
if(d>dp[i][k]+dp[k+][j]+sum[j]-sum[i-])
{
d=dp[i][k]+dp[k][j]+sum[j]-sum[i-];
id=k;
}
}
dp[i][j]=d;
s[i][j]=id;
}
printf("%d\n",dp[][n]);
return ;
}
dp优化-四边形不等式(模板题:合并石子)的更多相关文章
- 省选算法学习-dp优化-四边形不等式
嗯......四边形不等式的确长得像个四边形[雾] 我们在dp中,经常见到这样一类状态以及转移方程: 设$dp\left[i\right]\left[j\right]$表示闭区间$\left[i,j\ ...
- dp优化---四边形不等式与决策单调性
四边形不等式 定理1: 设w(x,y)为定义在整数集合上的二元函数,若存在任意整数a,b,c,d(a<=b<=c<=d),并且w(a,d)+w(b,c)>=w(a,c)+w(b ...
- 区间dp之四边形不等式优化详解及证明
看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...
- 【转】斜率优化DP和四边形不等式优化DP整理
(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- 区间DP的四边形不等式优化
今天上课讲DP,所以我学习了四边形不等式优化(逃 首先我先写出满足四边形不等式优化的方程:
- HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)
题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程 ...
- 『一维线性dp的四边形不等式优化』
四边形不等式 定义:设\(w(x,y)\)是定义在整数集合上的的二元函数,若对于定义域上的任意整数\(a,b,c,d\),在满足\(a\leq b\leq c \leq d\)时,都有\(w(a,d) ...
- DP 优化方法大杂烩 & 做题记录 I.
标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...
随机推荐
- 软件工程第六周psp
1.psp表格 类别 任务 开始时间 结束时间 中断时间 delta时间 立会 讲技术文档,分配任务 10月20日16:17 10月20日16:50 0 33分钟 准备工作 根据任务查资料 10月20 ...
- python学习第二天-基本数据类型常用方法
1.直入主题 python中基本的数据类型有 数字(整形,长整形,浮点型,复数) 字符串 字节串:在介绍字符编码时介绍字节bytes类型 列表 元组 字典 集合 下面我们直接将以下面几个点进行学习 # ...
- 原生js移动端可拖动进度条插件
该插件最初的想法来自网上的一篇文章,直达链接:https://www.cnblogs.com/libin-1/p/6220056.html 笔者因为业务需要寻找到这个插件,然后拿来用之,发现各种不方便 ...
- linux核心版本号的说明
日志不会很长,因为每天都在学习,我认为的重点,我自己做的记录,我很高兴能分享给大家: Linux的核心版本编号有点类似如下癿样子: 2.6.18-92.el5 主版本.次版本.释出版本-修改版本 因为 ...
- EasyUI 学习笔记
EasyUI常见错误 1 . 无论是用HMTL形式实现组件还是使用代码 + HTML 形式实现组件 , 在为组件设置属性时 , 要注意属性值的类型问题 string:必须加引号 number:不加任何 ...
- [OS] 多线程--原子操作 Interlocked系列函数
转自:http://blog.csdn.net/morewindows/article/details/7429155 上一篇<多线程--第一次亲密接触 CreateThread与_begint ...
- 【bzoj3437】小P的牧场 斜率优化dp
题目描述 背景 小P是个特么喜欢玩MC的孩纸... 描述 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个 ...
- 【bzoj1712】[Usaco2007 China]Summing Sums 加密 矩阵乘法
题目描述 那N只可爱的奶牛刚刚学习了有关密码的许多算法,终于,她们创造出了属于奶牛的加密方法.由于她们并不是经验十足,她们的加密方法非常简单:第i只奶牛掌握着密码的第i个数字,起始的时候是Ci(0≤C ...
- Linq的模糊查询(包含精确模糊查询)
目录: 1.判断是否为空或者null 2.普通包含模糊查询 1)以某字符串开头的模糊查询 2)以某字符串结尾的模糊查询 3)包含某字符串的模糊查询 3.精确到字符串对应位数字符的模糊查询(*重点) l ...
- CenOS 定时任务,at和crontab
1.一次性定时任务,只执行一次 语法:# at [参数] [时间] at> 执行的指令 退出at命令 ctrl+d 1.1 mini安装版本可能没有预装at 安装at yum -y instal ...