[BZOJ 1563] [NOI 2009] 诗人小G(决策单调性)
[BZOJ 1563] [NOI 2009] 诗人小G(决策单调性)
题面
一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以放的句子数目是没有限制的。小 G 给每首诗定义了一个行标准长度(行的长度为一行中符号的总个数),他希望排版后每行的长度都和行标准长度相差不远。显然排版时,不应改变原有的句子顺序,并且小 G 不允许把一个句子分在两行或者更多的行内。在满足上面两个条件的情况下,小 G 对于排版中的每行定义了一个不协调度, 为这行的实际长度与行标准长度差值绝对值的 P 次方,而一个排版的不协调度为所有行不协调度的总和。
小 G 最近又作了几首诗,现在请你对这首诗进行排版,使得排版后的诗尽量协调(即不协调度尽量小),并把排版的结果告诉他
\(n \leq 5\times 10^5\)
分析
转移方程推导
显然,设\(dp[i]\)为选了第\(i\)个句子并在此换行的最小不协调度。每句诗的长度为\(a[i]\),\(sum[i]\)为前\(i\)句诗的总长度,那么
\]
后面的式子表示把第\((j,i]\)句分成一行的代价。句子长度为\(sum[i]-sum[j]\),空格长度为\(i-j-1\)
这里的\(w\)函数为\(w(j,i)=|sum[i|-sum[j]+(i-j-1)-L|^P\),由于\(P\)的次数较高,无法斜率优化。于是尝试证明\(w\)满足四边形不等式
决策单调性证明
我们要证明\(\forall j<i,w(j,i+1)+w(j+1,i) \geq w(j,i)+w(j+1,i+1)\)
移项,得\(w(j+1,i)-w(j+1,i+1) \geq w(j,i)-w(j,i+1)\)
记:
\(u=(sum[i]+i)-(sum[j]+j)-(L+1)\)
\(v=(sum[i]+i)-(sum[j+1]+j+1)-(L+1)\)
则只需证明
\]
即证明对于任意常数\(c\),函数\(h(x)=|x|^P-|x+c|^P\)单调递减.证明比较繁琐,这里引用一下
总之,\(w\)满足四边形不等式,那么\(f\)有决策单调性
优化方法
由于单调性,每个决策\(x\)肯定存在一个区间\([l[x],r[x]]\)使得当前情况下\(p[k]=x(k \in[l[x],r[x]])\),
记\(pos(x,y)\)表示当前情况下,第一个以\(x\)为决策点不如以\(y\)为决策点更优的位置(如果当前只计算到\(dp[i]\),则对于\(i'>i\),\(p[i']=i\))。则\(r[x]=l[y]=pos(x,y)\).\(pos\)可以二分查找求出。
我们维护一个单调队列存储决策点。在处理\(dp[i]\)时,我们这样做:
如果队头的决策点对应区间不包含i,即\(r[q[head]]=pos(q[head],q[head+1])<i\)则出队
通过队头决策点转移
通过二分寻找出最左边的,以\(q[tail]\)为决策点不如以i为决策点更优的位置。这个位置实际上是\(l[i]\).由于决策单调性,目前从这个位置往右的 dp 都满足以i为决策点是最优的。再二分出\(l[q[tail]]=pos(q[tail-1],q[tail])\),如果\(l[i]<r[q[tail]]\),说明\(q[tail]\)决策点对应的所有转移都不如\(i\)更优,我们把\(q[tail]\)出队,继续比较下一个决策点
当队尾的弹出停止的时候,将\(i\)入队,且\(i\)对应区间右端点为\(n\)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 500000
#define maxl 30
#define INF 1e18
using namespace std;
typedef long double db;
int T;
int n,L,P;
char s[maxn+5][maxl+5];
int sum[maxn+5];
db dp[maxn+5];
int res[maxn+5];
inline db fast_pow(db x,int k){
db ans=1;
while(k){
if(k&1) ans=ans*x;
x=x*x;
k>>=1;
}
return ans;
}
inline db calc(int j,int i){//计算f[j]+val(j,i)
return dp[j]+fast_pow(abs(sum[i]-sum[j]+(i-j-1)-L),P);
}
inline int bin_search(int a,int b){//找到第一个决策b比决策a优的位置
if(calc(a,n)<calc(b,n)) return n+1;
int l=b,r=n;
int ans=-1;
int mid;
while(l<=r){
mid=(l+r)>>1;
if(calc(b,mid)<=calc(a,mid)){
ans=mid;
r=mid-1;
}else l=mid+1;
}
return ans;
}
void ini(){
for(int i=1;i<=n;i++){
dp[i]=INF;
res[i]=0;
}
}
int q[maxn+5];
int stk[maxn+5];//找出1~n最优决策的每一段
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&L,&P);
ini();
for(int i=1;i<=n;i++){
scanf("%s",s[i]);
sum[i]=strlen(s[i])+sum[i-1];
}
int head=1,tail=0;
q[++tail]=0;
dp[0]=0;
for(int i=1;i<=n;i++){
while(head<tail&&bin_search(q[head],q[head+1])<=i) head++;
//使得head决策点的对应区间包含i
res[i]=q[head];
dp[i]=calc(q[head],i);
while(head<tail&&bin_search(q[tail-1],q[tail])>=bin_search(q[tail],i)) tail--;
//把以队尾决策点为决策点不如以i为决策点更优的位置出队
q[++tail]=i; //并替换成i
}
if(dp[n]>INF){
printf("Too hard to arrange\n");
}else{
printf("%lld\n",(long long)dp[n]);
int top=0;
for(int i=n;i;i=res[i]) stk[++top]=i;
stk[++top]=0;
for(int i=top-1;i>=1;i--){
int r=stk[i],l=stk[i+1]+1;
for(int j=l;j<r;j++) printf("%s ",s[j]);
printf("%s\n",s[r]);
// }
}
printf("--------------------\n");
}
}
[BZOJ 1563] [NOI 2009] 诗人小G(决策单调性)的更多相关文章
- bzoj1563: [NOI2009]诗人小G 决策单调性(1D1D)
目录 题目链接 题解 代码 题目链接 bzoj1563: [NOI2009]诗人小G 题解 \(n^2\) 的dp长这样 \(f_i = min(f_j + (sum_i - sum_j - 1 - ...
- NOI 2009 诗人小G
题目描述 Description 小G是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行 ...
- 解题:NOI 2009 诗人小G
题面 今天考试考了,于是开始糊学决策单调性DP 这是一个完全不会优化DP的人 决策单调性DP的一种优化方法是用单调队列优化 存下{左端点l,右端点r,最优决策点p}的三元组,按照单调队列的通常操作来说 ...
- [NOI2009]诗人小G 决策单调性优化DP
第一次写这种二分来优化决策单调性的问题.... 调了好久,,,各种细节问题 显然有DP方程: $f[i]=min(f[j] + qpow(abs(sum[i] - sum[j] - L - 1))); ...
- BZOJ1563: [NOI2009]诗人小G(决策单调性 前缀和 dp)
题意 题目链接 Sol 很显然的一个dp方程 \(f_i = min(f_j + (sum_i - sum_j - 1 - L)^P)\) 其中\(sum_i = \sum_{j = 1}^i len ...
- P1912 [NOI2009]诗人小G[决策单调性优化]
地址 n个数划分若干段,给定$L$,$p$,每段代价为$|sum_i-sum_j-1-L|^p$,求总代价最小. 正常的dp决策单调性优化题目.不知道为什么luogu给了个黑题难度.$f[i]$表示最 ...
- 【BZOJ 1563】 [NOI2009]诗人小G
Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...
- [BZOJ1563][NOI2009]诗人小G(决策单调性优化DP)
模板题. 每个决策点都有一个作用区间,后来的决策点可能会比先前的优.于是对于每个决策点二分到它会比谁在什么时候更优,得到新的决策点集合与区间. #include<cstdio> #incl ...
- BZOJ1563:[NOI2009]诗人小G(决策单调性DP)
Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...
随机推荐
- JavaWeb_(Struts2框架)Struts创建Action的三种方式
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- 2016 CCPC 长春站现场赛总结(流水账= =)
总的来说在写这篇总结的时候心情还是愉悦的,因为第一次参加区域赛就越过铜直接拿了个银~开心之情无法用语言形容啊233= =... 从杭州坐火车到长春,去的时候24个小时,回来32个小时,在路上就花了2天 ...
- Android学习_内容提示器
内容提供器 1. 创建自己的内容提供器 1) 继承ContentProvider类,重写6个方法:onCreate().query().insert().update().delete ...
- ccf 201703-4 地铁修建(95)(并查集)
ccf 201703-4 地铁修建(95) 使用并查集,将路径按照耗时升序排列,依次加入路径,直到1和n连通,这时加入的最后一条路径,就是所需要修建的时间最长的路径. #include<iost ...
- 反射 go
reflect.Valueof 到底是个什么? 反射值对象(reflect.Value)提供一系列方法进行零值和空判定,如下表所示. 反射值对象的零值和有效性判断方法 方 法 说 明 IsNil() ...
- leetcode1281 整数的各位积和之差
class Solution { public: int subtractProductAndSum(int n) { ; ; ){ ; n/=; prod*=r; add+=r; } int res ...
- python - linux下 no module named pip
有网络的情况下,linux系统提示无法使用pip命令: 有两种解决方式: 第一种: =============================== 敲命令:python -m ensurepip 得到 ...
- 2019-8-12未命名文件 sdfsf
2019-8-12未命名文件 sdfsf 新建模板小书匠 欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 小书匠主按钮>模板 里的模板管理来改变新建文章的内容.sdfsdfsdf
- 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串
import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...
- 加密算法之 MD5算法
题记:本人自测了很多次,该算法和apache的commons utils包中的MD5算法计算一致 一.针对文件内容生成MD5值 应用场景:针对文件,在传输过程由于网络原因丢帧或者被人别恶意篡改内容,可 ...