【题解】Typesetting [Hdu6107]
【题解】Typesetting [Hdu6107]
传送门:\(\text{Typesetting}\) \(\text{[Hdu6107]}\)
【题目描述】
有一篇行数无限宽度 \(MaxW\) 已知的文章,中间有张图片,图片的高度 \(h\) 和放置的位置 \(x\) 可以任意,有若干个长度 \(a[i]\) 已知的词,要保持整个词的完整性,词和词不能重叠,词和图不能重叠,词必须从第一行开始放,词的顺序不能改变,词和词连续放在一行时中间要空一行,问放完所有的词和图片所需的最少行数。
【输入】
首先读入一个整数 \(T\) 表示一共有 \(T\) 组数据,对于每组数据,将会包括以下内容:
第一行四个整数 \(n,MaxW,PW,LW\) 分别表示单词个数,文章宽度,图片宽度和图片左间距(表示图片与左边界相隔的宽度),图片右间距自行计算。
第二行 \(n\) 个整数 \(a_i\) 表示每个单词的长度。
第三行一个整数 \(Q\),表示接下来有 \(Q\) 个询问,接下来 \(Q\) 行,每行两个整数 \(x,h\),表示图片将从第 \(x\) 行开始一共占 \(h\) 行的位置。
【输出】
对于每个询问,输出此时放完所有单词需要的最少行数。
【样例】
样例输入:
2
2 7 4 3
1 3
3
1 2
2 2
5 2
3 8 2 3
1 1 3
1
1 1
样例输出:
2
3
3
1
【数据范围】
\(100 \%:\)
\(T \leqslant 10\)
\(1 \leqslant n,Q,MaxW \leqslant 10^5\)
\(1 \leqslant a_i,PW \leqslant MaxW\)
\(0 \leqslant LW \leqslant MaxW-Pw\)
【分析】
图片的存在很讨厌,可以把有图片和没有图片的分开处理,步骤如下:
\((1).\) 先算 \(x-1\) 行(对应着 \([1,x-1]\))能放多少单词。
\((2).\) 如果放不完的话,再算在只用一部分合法空间的情况下 \(h\) 行(对应着 \([x,x+h-1]\))能放多少单词。
\((3).\) 如果还是没放完,再算剩下的单词需要多少行。
上述过程均可用倍增实现,用 \(dp_{1}[i][j]\) 表示在没有图片的情况下,从第 \(i\) 个单词开始放,使用 \(2^j\) 行可以放的单词个数,\(dp_{2}[i][j]\) 表示在有图片的情况下,只使用左右间距构成的空间,\(2^j\) 行可以放的单词个数,照着上面的思路模拟一下就可以了。
【Code】
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define Re register int
using namespace std;
const int N=1e5+3,logN=17;
int n,x,y,T,Q,PW,LW,RW,maxW,a[N],dp1[N][20],dp2[N][20];
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline void sakura(){//预处理
for(Re i=1,j,tmp,flag;i<=n;++i){
//dp1[i][j]: 从第i个单词开始(包括i),使用2^j行可以放的单词个数
j=i-1,tmp=0,flag=0;//flag表示是否要添空格
while(j<n&&tmp+flag+a[j+1]<=maxW)++j,tmp+=a[j]+flag,flag=1;//暴力枚举初始化
dp1[i][0]=j-i+1;
//dp2[i][j]: 从第i个单词开始(包括i),使用被图片覆盖的2^j行可以放的单词个数
j=i-1,tmp=0,flag=0;
while(j<n&&tmp+flag+a[j+1]<=LW)++j,tmp+=a[j]+flag,flag=1;//左间距
tmp=0,flag=0;
while(j<n&&tmp+flag+a[j+1]<=RW)++j,tmp+=a[j]+flag,flag=1;//右间距
dp2[i][0]=j-i+1;
}
for(Re j=1;j<=logN;++j)
for(Re i=1;i<=n;++i){
if(dp1[i][j-1])dp1[i][j]=dp1[i][j-1]+dp1[i+dp1[i][j-1]][j-1];//要注意判断,如果前半部分放不了的话
if(dp2[i][j-1])dp2[i][j]=dp2[i][j-1]+dp2[i+dp2[i][j-1]][j-1];//不管后半部分怎么折腾都没用
}
}
inline int find1(Re i,Re limit,Re dp[][20]){//从第i个单词开始(现在需要放的位置),使用limit行,条件为dp1/dp2,求无法放到第?个单词
Re tmp=0;//tmp: 已经使用的行数
for(Re j=logN;j>=0;--j)
if(tmp+(1<<j)<=limit)
i+=dp[i][j],tmp+=(1<<j);
return i;
}
inline int find2(Re i){//在无图片的情况下,放第i~n个单词个单词需要多少行
Re ans=0;
for(Re j=logN;j>=0;--j)//不管j有多大,i+dp[i][j]-1永远都<=n
if(i+dp1[i][j]-1<n)//为了不造成浪费,要找到不能一次全部放完的最大的j,即满足i+dp1[i][j]-1<n
ans+=(1<<j),i+=dp1[i][j];
if(i<=n)ans+=(1<<0),i+=dp1[i][0];//如果i!=n+1,使用一下dp1[i][0]把剩下的全部放完
return ans;
}
int main(){
// freopen("123.txt","r",stdin);
in(T);
while(T--){
in(n),in(maxW),in(PW),in(LW);
RW=maxW-PW-LW;//maxW:最大宽度 //PW:图片宽度 //LW:左间距 //RW:右间距
for(Re i=1;i<=n;++i)in(a[i]);
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
sakura();
in(Q);
while(Q--){
in(x),in(y);
Re need=find2(1);
if(need<x){printf("%d\n",need+y);continue;}//不需要使用覆盖图片的部分就可以全部放完
Re now=find1(1,x-1,dp1);//先跑前面无限制的x-1行
now=find1(now,y,dp2);//再跑覆盖图片的y行
printf("%d\n",x-1+y+find2(now));//最后看还需要再跑多少无图片的行
}
}
}
【题解】Typesetting [Hdu6107]的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- Java SPI机制实战详解及源码分析
背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...
- MySQL(11)---约束
MySQL(11)---约束 含义: 一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性. 先把Mysql几种约束列出来: 主键约束 外键约束 唯一性约束 非空约束 默认值约束 自增约束 ...
- 帝国CMS标签【操作类型】说明详解
看标签的参数时候,一般最后一个参数是操作类型说明,可是后面写的是:"操作类型说明 具体看操作类型说明", 这个操作类型说明在什么地方看啊 操作类型 说明 操作类型 说明 0 各栏目 ...
- Winform中在使用Dock属性设计页面布局控件的顺序导致页面效果不同的问题
场景 在Winform中进行页面设计时,常使用控件的Dock属性来进行布局调整.但是由于设置属性的顺序问题,导致达不到想要的效果. 比如以下两个控件 下面的控件设置的Dock属性是Bottom,即在页 ...
- Spring Boot 之异步执行方法
前言: 最近的时候遇到一个需求,就是当服务器接到请求并不需要任务执行完成才返回结果,可以立即返回结果,让任务异步的去执行.开始考虑是直接启一个新的线程去执行任务或者把任务提交到一个线程池去执行,这两种 ...
- C# abstract 和 interface 区别
抽象类主要用来提供多个派生类可共享的基类的公共定义,它与非抽象类的主要区别如下: 抽象类不能直接实例化. 抽象类中可能包含抽象成员,但非抽象类中不可以. 抽象类不能被密封. 接口具有以下特征 接口类类 ...
- MYSQL 复制整个数据库
同一个服务器 mysqldump old -u root -p123456 | mysql new -u root -p123456 不同服务器(在源数据库服务器上执行) mysqldump old ...
- 重新安装和更新所有的 nuget包
重新安装指定项目中所有的 nuget 包 Update-Package -ProjectName MyProject –reinstall 更新指定项目中所有的 nuget 包 Update-Pack ...
- 0基础入门学习Python(第4章)
第四章,了不起的分支和循环 4.1 分支和循环 Python主要依靠缩进来区分代码块 4.2 快速上手 成绩按照分数来划分等级,90分以上为A,80~90 为B,60~80 为C,60以下为D p4_ ...
- SQLi-LABS Page-4 (Challenges) Less-54-Less-65
Less-54 union - 1 http://10.10.202.112/sqli/Less-54?id=-1' union select 1,2,group_concat(table_name) ...