『一维线性dp的四边形不等式优化』
<更新提示>
<正文>
四边形不等式
定义:设\(w(x,y)\)是定义在整数集合上的的二元函数,若对于定义域上的任意整数\(a,b,c,d\),在满足\(a\leq b\leq c \leq d\)时,都有\(w(a,d)+w(b,c)\geq w(a,c)+w(b,d)\)成立,则称函数\(w\)满足四边形不等式。
定理1:四边形不等式的等价表达
\(w(x,y)\)是定义在整数集合上的的二元函数,若对于定义域上的任意整数\(a,b\),在满足\(a< b\)时,都有\(w(a,b+1)+w(a+1,b)\geq w(a,b)+w(a+1,b+1)\)成立,则称函数\(w\)满足四边形不等式。
证明:
设\(a<c\),则有\(w(a,c+1)+w(a+1,c)\geq w(a,c)+w(a+1,c+1)\)。
若\(a+1<c\),则有\(w(a+1,c+1)+w(a+2,c)\geq w(a+1,c)+w(a+2,c+1)\)。
两式相加,消去相同项可得:\(w(a,c+1)+w(a+2,c)\geq w(a,c)+w(a+2,c+1)\)。
类似的,只要\(a+k<c\)就可以得到:\(w(a,c+1)+w(a+k,c)\geq w(a,c)+w(a+k,c+1)\)。
所以对于\(a\leq b\leq c\),就有\(w(a,c+1)+w(b,c)\geq w(a,c)+w(b,c+1)\)。
同理可证对于\(a\leq b\leq c\leq d\),有\(w(a,d)+w(b,c)\geq w(a,c)+w(b,d)\)。
定理2:决策单调性
定义:对于形如\(f[i]=min_{0\leq j <i}\{f[j]+val(j,i)\}\)的状态转移方程,记\(p[i]\)为\(f[i]\)的最优决策。若\(p\)在\([1,n]\)上单调不减,则称\(f\)具有决策单调性。
在状态转移方程\(f[i]=min_{0\leq j <i}\{f[j]+val(j,i)\}\)中,若函数\(val\)满足四边形不等式,则\(f\)具有决策单调性。
证明:
对于\(\forall i\in[1,n],\forall j\in[0,p[i]-1]\),由\(p[i]\)的最优性可得:$$f[p[i]]+val(p[i],i)\leq f[j]+val(j,i)\tag1$$
设有\(i'\in[i+1,n]\),因为\(val\)满足四边形不等式,所以$$val(j,i')+val(p[i],i)\geq val(j,i)+val(p[i],i')$$
整理可得:
\]
\((1)(2)\)两式相加,可得:
\]
所以,对于\(i\)以后的任意一个\(i'\),\(p[i]\)都是比任意\(j<p[i]\)更优的决策,故\(f\)具有决策单调性。
诗人小G
Description
小G是一个出色的诗人,经常作诗自娱自乐。但是,他一直被一件事情所困扰,那就是诗的排版问题。
一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中, 注意一行中可以放的句子数目是没有限制的。小G给每首诗定义了一个行标准长度(行的长度为一行中符号的总个数),他希望排版后每行的长度都和行标准长度相差不远。显然排版时,不应改变原有的句子顺序,并且小G不允许把一个句子分在两行或者更多的行内。在满足上面两个条件的情况下,小G对于排版中的每行定义了一个不协调度, 为这行的实际长度与行标准长度差值绝对值的P次方,而一个排版的不协调度为所有行不协调度的总和。
小G最近又作了几首诗,现在请你对这首诗进行排版,使得排版后的诗尽量协调(即不协调度尽量小),并把排版的结果告诉他。
Input Format
输入包含多组数据。
第一行包含一个整数T,表示诗的数量,接下来是T首诗,这里一首诗即为一组数据。每组数据的第一行包含三个由空格分隔的正整数N、L、P,其中N表示这首诗句子的数目,L表示这首诗的行标准长度,P的含义见问题描述。从第2行开始,每行为一个句子,句子由英文字母、数字、标点符号等符号组成(ASCII码33~127, 但不包含 ‘-’)。
Output Format
对于每组数据,若最小的不协调度不超过10181018,则一行一个数表示不协调度,若最小的不协调度超过10181018,则输出"Too hard to arrange"(不包含引号)。每组数据结束后输出"--------------------"(不包括引号),共20个"-","-"的ASCII码为45,请勿输出多余的空行或者空格。
Sample Input
4
4 9 3
brysj,
hhrhl.
yqqlm,
gsycl.
4 9 2
brysj,
hhrhl.
yqqlm,
gsycl.
1 1005 6
poet
1 1004 6
poet
Sample Output
108
--------------------
32
--------------------
Too hard to arrange
--------------------
1000000000000000000
--------------------
解析
设\(f[i]\)代表对前\(i\)句诗版排的最小不协调度,\(a[i]\)为第\(i\)句诗的长度,\(sum[i]\)为\(a[i]\)的前缀和。
\]
其中,设\(val(j,i)=|sum[i]-sum[j]+i-j-1-L|^P\),那么方程符合上述四边形不等式中提到的状态转移方程的格式。
我们可以证明函数\(val(j,i)\)满足四边形不等式,进而得知\(f\)具有决策单调性,也可以打标发现\(f\)具有决策单调性。现在,我们讨论如何利用决策单调性对动态规划进行优化。
我们首先考虑维护决策数组\(p\),首先它一定是单调不减的。对于求出一个新的状态\(f[i]\)后,我们要考虑\(i\)可以作为哪些状态的最优决策。由决策单调性可知,数组\(p\)中一定存在一个最小位置\(pos\),使得\([pos,n]\)中的所有决策都劣于\(i\),我们需要将\(p\)数组中下标在\([pos,n]\)的值都改为\(i\)。
在数组上大量修改时很费时的,我们不妨用一个队列来代替\(p\)数组,在队列中存储若干个三元组\((j,l,r)\),代表\(p\)数组中\([l,r]\)位置的值都为\(j\),这样我们就可以高效地维护队列了。
对于一个新的状态\(f[i]\),我们先将队头已经过时的决策弹出,然后取队头决策就可以进行转移。
如何加入一个决策\(i\)呢?我们可以将决策\(i\)与队尾的决策逐个比较,如果\(i\)优于队尾的某个整段决策,就将整段决策弹出队列,直到队列为空。或者,遇到某一段决策,\(i\)不比整段决策优,那就在这段决策中进行二分查找,找到最小的\(pos\)即可。
最后,我们加入决策\(i\),有效范围为\([pos,n]\)。当然,如果\(pos\)处于原本的一段中间,则还需修改原本队尾决策的右端点。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+20;
const long long INF = 1e18;
struct state{int j,l,r;}q[N];
int n,L,p,a[N];
long double f[N],sum[N];
char poem[40];
inline void input(void)
{
scanf("%d%d%d",&n,&L,&p);
for (int i=1;i<=n;i++)
{
scanf("%s",poem);
a[i] = strlen(poem);
sum[i] = sum[i-1] + a[i];
}
}
inline long double power(long double val)
{
if ( val < 0 ) val = -val;
long double res = 1;
int p_ = p;
while ( p_ )
{
if ( 1 & p_ ) res *= val;
p_ >>= 1 , val *= val;
}
return res;
}
inline long double calc(int i,int j)
{
return f[j] + power( sum[i] - sum[j] + i - j - 1 - L );
}
inline int binary_search(state T,int i)
{
int l = T.l , r = T.r;
while ( l + 1 < r )
{
int mid = (l+r) >> 1;
if ( calc( mid , T.j ) < calc( mid , i ) )
l = mid;
else r = mid;
}
if ( calc( l , T.j ) >= calc( l , i ) ) return l;
if ( calc( r , T.j ) >= calc( r , i ) ) return r;
return r+1;
}
inline void dp(void)
{
int head = 1 , tail = 0 , pos;
f[0] = 0 , q[++tail] = (state){0,1,n};
for (int i=1;i<=n;i++)
{
while ( head <= tail && q[head].r < i ) head++;
f[i] = calc( i , q[head].j );
if ( head > tail || calc(n,i) <= calc(n,q[tail].j) )
{
while ( head <= tail && calc(q[tail].l,i) <= calc(q[tail].l,q[tail].j) ) tail--;
if ( head > tail )
q[++tail] = (state){i,i+1,n};
else
{
int pos = binary_search(q[tail],i);
q[tail].r = pos-1;
q[++tail] = (state){i,pos,n};
}
}
}
}
int main(void)
{
int T;
scanf("%d",&T);
while (T--)
{
input();
dp();
if ( f[n] > INF ) puts("Too hard to arrange");
else printf("%lld\n",(long long)f[n]);
puts("--------------------");
}
return 0;
}
<后记>
『一维线性dp的四边形不等式优化』的更多相关文章
- 【转】斜率优化DP和四边形不等式优化DP整理
(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...
- 区间DP的四边形不等式优化
今天上课讲DP,所以我学习了四边形不等式优化(逃 首先我先写出满足四边形不等式优化的方程:
- 区间dp之四边形不等式优化详解及证明
看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...
- HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)
题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程 ...
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- CF321E Ciel and Gondolas Wqs二分 四边形不等式优化dp 决策单调性
LINK:CF321E Ciel and Gondolas 很少遇到这么有意思的题目了.虽然很套路.. 容易想到dp \(f_{i,j}\)表示前i段分了j段的最小值 转移需要维护一个\(cost(i ...
- hdu 2829 Lawrence(四边形不等式优化dp)
T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in ...
- BZOJ1563/洛谷P1912 诗人小G 【四边形不等式优化dp】
题目链接 洛谷P1912[原题,需输出方案] BZOJ1563[无SPJ,只需输出结果] 题解 四边形不等式 什么是四边形不等式? 一个定义域在整数上的函数\(val(i,j)\),满足对\(\for ...
随机推荐
- Easypoi实现单模板生成多页wrod文档
EasyPoi可以很方便的通过一个word模板,然后通过填充模板的方式生成我们想要的word文档.但是碰到了一个单模板生成多页数据的场景,比如一个订单详情信息模板,但是有很多订单,需要导入到一 ...
- 设计模式 行为型 - 策略模式 Strategy
策略模式(Strategy) 意图 对象有某个行为,但是在 不同的场景 下,该行为有 不同的实现算法. 就好比你去餐馆吃饭,首页你要通过菜单来选择你想吃的菜,根据你点的菜的不同,在厨房中去做不同的菜. ...
- django_restframework项目之python虚拟环境配置(一)
虚拟环境的搭建 优点 1.使不同应用开发环境相互独立 2.环境升级不影响其他应用,也不会影响全局的python环境 3.防止出现包管理混乱及包版本冲突 windows 安装 # 建议使用pip3安装到 ...
- elastalert docker安装
基于对elasticsearch中数据监控需要,我尝试了sentinl和elastalert两款工具.虽然elastalert是纯文本,但易配置管理.elk自带的watch需要付费才可使用. 6.2x ...
- nginx 日志问题(\x22)
nginx 日志问题(\x22) 问题: 1.request_body中含有中文时,nginx日志会转换为十六进制. 2.nginx记录问题 POST /xxxxx HTTP/1.1|200|4266 ...
- 【jsp】案例:显示商品列表 & 问题:List内添加元素,为什么值都变成一样的了
代码: 1.Product: package domain; public class Product { /* `pid` varchar(50) NOT NULL, `pname` varchar ...
- 腾讯面试Android高级岗,居然被一个多线程基础面倒了?
前言 一个在深圳从事开发五年的老友一个月前从原公司辞职后,昨天去腾讯总部面试Android高级岗,一面的时候,自我介绍后,陆陆续续问了很多问题,有着五年的从业经验很多项目开发的技术问题都回答的很通顺, ...
- Flutter gradle采坑
前些日子google推出Flutter1.9版本支持web果断升级 在运行flutter时发现错误,错误提示为 Launching lib/main.dart on Android SDK built ...
- python网页内容提取神器lxml
一.Xpath是什么 XPath 是一门在 XML 文档中查找信息的语言.XPath 用于在 XML 文档中通过元素和属性进行导航. XPath 使用路径表达式在 XML 文档中进行导航 XPath ...
- MyISAM引擎mysql5.6中大型网站数据库优化配置方案
硬件服务器:Dell R710,双至强E5620 CPU.16G内存.6*500G硬盘 操作系统:CentOS5.5 X86_64 系统 Mysql版本:MySQL 5.6 适用于:日IP ...