诗人小G

题目大意

给出 \(n\) 个长度不超过 \(30\) 的句子,要求你对其进行排版。

对于每一行,有一个规定的行标准长度 \(L\) ,每一行的不协调度等于该行的实际长度与行标准长度差的绝对值的 \(P\) 次方,而每一个排版的不协调度为所有行不协调度的总和。

每一行可以放入若干个句子,相邻的两个句子之间用空格隔开,每行的实际长度为该行拥有的字符数量(空格算一个字符)。

分析

https://www.cnblogs.com/Defoliation-ldlh/p/14988380.html

首先我们比较容易想到 \(DP\) 。

设 \(f[i]\) 表示前 \(i\) 句诗排版的最小不协调度,很显然,状态转移方程为:

\[f[i]=min \{ f[j]+|sum[i]-sum[j]+(i-j-1)-L|^p \} (0\le j\le i)
\]

很显然此时时间复杂度为 \(O(n^2)\) ,并不能解决该问题。

注意到我们可以设 \(val(i,j)=|sum[i]-sum[j]+(i-j-1)-L|^p\) ,因此我们可以证明 \(val(i,j)\) 满足四边形不等式,那我们的 \(DP\) 就会满足决策单调性,凭此我们能够达到优化该 \(DP\) 的目的。

下证 \(val(i,j)\) 满足四边形不等式:

当然,该证明并不太严格,严格证明需要讨论 \(x<-c,-c \le x\le 0,x>0\) 与 \(p\) 的奇偶性,加上求导即可证明。

于是,我们可以发现该 \(DP\) 具有决策单调性,因此可以直接使用前置知识中的方法求出最终的答案。

坑点

这题坑点比较多,首先是会爆掉 \(long long\) ,使用 \(long double\) 储存位数更多一些。还有就是不能输出多余的空格和回车,否则也会 \(WA\) 掉。

CODE

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long double ld;
const int N=1e5+10,INF=1e18;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') w*=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
struct node{
int l,r,p;
}arr[N]; //队列封装所有状态
int T,n,L,P,st,nd;
int num[N];
char sten[N][31]; //由于要输出,记录下输入的句子
int sum[N]; //记录句子长度的前缀和
ld f[N];
int g[N]; //g数组记录最佳决策点
inline ld power(ld x,int k) //快速幂,大材小用
{
if(x<0) x=-x; //防止结果返回负数
ld res=1;
while(k){
if(k&1) res=res*x;
x=x*x,k>>=1;
}
return res;
}
inline void in()
{
char ch=getchar();
for(register int i=1;i<=n;i++){
int l=0;
while((int)ch<33||(int)ch>127||ch=='-') ch=getchar();
while((int)ch>=33&&(int)ch<=127&&ch!='-') sten[i][++l]=ch,ch=getchar();
num[i]=l; //记录单个句子长度,方便输出
sum[i]=sum[i-1]+num[i]; //更新前缀和
}
}
inline int find(node now,int x)
{
int ans=now.r;
int l=now.l,r=now.r,v=now.p;
while(l<=r){
int mid=(l+r)/2;
ld com1=f[x]+power(sum[mid]-sum[x]+(mid-x-1)-L,P);
ld com2=f[v]+power(sum[mid]-sum[v]+(mid-v-1)-L,P);
if(com1<=com2) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
inline void update(int x)
{
int pos=-1;
for(register int i=nd;i>=st;i--){
node now=arr[i];
ld temp1=f[x]+power(sum[now.l]-sum[x]+(now.l-x-1)-L,P);
ld temp2=f[now.p]+power(sum[now.l]-sum[now.p]+(now.l-now.p-1)-L,P); //左区间端点
ld temp3=f[x]+power(sum[now.r]-sum[x]+(now.r-x-1)-L,P);
ld temp4=f[now.p]+power(sum[now.r]-sum[now.p]+(now.r-now.p-1)-L,P); //右区间端点
if(temp1<=temp2) pos=now.l,nd--;
else if(temp3>temp4) break;
else { pos=find(now,x),arr[i].r=pos-1; break; }
}
if(pos==-1) return;
arr[++nd].l=pos;
arr[nd].r=n,arr[nd].p=x;
}
inline void out(int x,int last)
{
if(x==0) return;
out(g[x],x);
for(register int i=g[x]+1;i<=x;i++){
for(register int j=1;j<=num[i];j++) printf("%c",sten[i][j]);
if(i<x) printf(" ");
}
puts("");
}
signed main()
{
T=read();
while(T--){
n=read(),L=read(),P=read();
in(); //读入
st=nd=1; //队首队尾皆为1,
arr[st].l=1,arr[st].r=n,arr[st].p=0;
for(register int i=1;i<=n;i++){
node now=arr[st]; //取出队头
f[i]=f[now.p]+power(sum[i]-sum[now.p]+(i-now.p-1)-L,P);
g[i]=now.p; //记录当前点的最佳决策点
if(now.r>i) arr[st].l=i+1;
else st++; //队头出队
update(i); //更新队列
}
if(f[n]>INF||f[n]<0) puts("Too hard to arrange");
else{
int ans=f[n];
printf("%lld\n",ans);
out(g[n],n);
for(register int i=g[n]+1;i<=n;i++){
for(register int j=1;j<=num[i];j++) printf("%c",sten[i][j]);
if(i<n) printf(" ");
}
puts("");
}
if(T) puts("--------------------");
}
printf("--------------------");
return 0;
}

[NOI2009] 诗人小G [题解]的更多相关文章

  1. bzoj1563: [NOI2009]诗人小G 决策单调性(1D1D)

    目录 题目链接 题解 代码 题目链接 bzoj1563: [NOI2009]诗人小G 题解 \(n^2\) 的dp长这样 \(f_i = min(f_j + (sum_i - sum_j - 1 - ...

  2. 1563: [NOI2009]诗人小G

    1563: [NOI2009]诗人小G https://lydsy.com/JudgeOnline/problem.php?id=1563 分析: 直接转移f[i]=f[j]+cost(i,j),co ...

  3. [NOI2009]诗人小G --- DP + 决策单调性

    [NOI2009]诗人小G 题目描述: 小G是一个出色的诗人,经常作诗自娱自乐. 但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并 ...

  4. P1912 [NOI2009]诗人小G

    P1912 [NOI2009]诗人小G 思路: 平行四边形不等式优化dp 因为f(j, i) = abs(sum[i]-sum[j]+i-j-1-l)^p 满足平行四边形不等式 j < i f( ...

  5. LG1912 [NOI2009]诗人小G

    题意 题目描述 小G是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以 ...

  6. 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)

    洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...

  7. NOI2009 诗人小G

    Sol 决策单调性+二分 传说中的四边形不等式...其实做了这道题还是不会... 证明简直吃屎//// 贴个传送门这里有部分分做法还有决策单调性的证明 byvoid ISA tell me that ...

  8. 【BZOJ 1563】 [NOI2009]诗人小G

    Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...

  9. bzoj1563: [NOI2009]诗人小G

    Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...

随机推荐

  1. 使用vue-i18n实现中英文切换(内含动态属性的绑定)

    最近做学生管理系统,因为有国外的学生,所以要进行中英文切换,查了查Vue中使用vue-i18n插件能够实现网页的中英文切换,学习内容如下: 一.下载vue-i18n插件 npm install vue ...

  2. WPF中Grid容器中VerticalAlignment和HorizonAlignment和Margin的关系。

    在WPF中,经常使用Grid容器,来布局我们想要显示的对象. 这就不可避免的要和布局在其中的控件的VerticalAlignment特性,HorizonAlignment特性,以及Magin特性打交道 ...

  3. 鱼眼摄像头SLAM

    鱼眼摄像头SLAM 在机器人技术.摄影测量学和计算机视觉等领域,鲁棒相机位姿估计是许多视觉应用的核心.近年来,在复杂.大规模的室内外环境中,人们越来越关注相机位姿估计方法的实时性.通用性和可操作性.其 ...

  4. YOLO3升级优化版!Poly-YOLO:支持实例分割!

    YOLO3升级优化版!Poly-YOLO:支持实例分割! POLY-YOLO: HIGHER SPEED, MORE PRECISE DETECTION AND INSTANCE SEGMENTATI ...

  5. Linux架构思维导图

    Linux架构思维导图 GUI(Graphical User Interface,图形用户界面) Linux学习路径 软件框架 Linux桌面介绍 FHS:文件系统目录标准 Linux需要特别注意的目 ...

  6. halcon——缺陷检测常用方法总结(光度立体)

    引言 机器视觉中缺陷检测分为一下几种: blob+特征(官方示例surface_scratch.hdev) blob+差分+特征(官方示例pcb_inspection.hdev) 光度立体 特征训练 ...

  7. JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace

    直接上代码: public class Test001 { public static void main(String[] args) { //java.lang.StackOverflowErro ...

  8. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    一.背景 人脸识别是近年来最热门的计算机视觉领域的应用之一,而且现在已经出现了非常多的人脸识别算法,如:DeepID.FaceNet.DeepFace等等.人脸识别被广泛应用于景区.客运.酒店.办公室 ...

  9. .NET平台系列23:.NET Core/.NET5/.NET6 和 .NET Framework 的选择建议

    系列目录     [已更新最新开发文章,点击查看详细] 有两种支持的 .NET 实现可用于生成服务器端应用: .NET Framework .NET Core/5+,包括 .NET Core..NET ...

  10. CSS3-过渡、动画、2D与3D

    过渡 过渡属性transition,可适用于大部分属性间变化的过渡,例如长度的.宽度和透明度等等. 语法: transition: property duration timing-function ...