Typesetting HDU - 6107
The page width is fixed to W characters. In order to make the article look more beautiful, Yellowstar has made some rules:
1. The fixed width of the picture is pw. The distance from the left side of the page to the left side of the photo fixed to dw, in other words, the left margin is dw, and the right margin is W - pw - dw.
2. The photo and words can't overlap, but can exist in same line.
3. The relative order of words cannot be changed.
4. Individual words need to be placed in a line.
5. If two words are placed in a continuous position on the same line, then there is a space between them.
6. Minimize the number of rows occupied by the article according to the location and height of the image.
However, Yellowstar has not yet determined the location of the picture and the height of the picture, he would like to try Q different locations and different heights to get the best look. Yellowstar tries too many times, he wants to quickly know the number of rows each time, so he asked for your help. It should be noted that when a row contains characters or pictures, the line was considered to be occupied.
InputThe first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with four integers N, W, pw, dw : the number of words, page width, picture width and left margin.
The next line contains N integers aiai, indicates i-th word consists of aiai characters.
The third line contains one integer Q.
Then Q lines follow, each line contains the values of xi and hi, indicates the starting line and the image height of the image.
Limits
T≤10T≤10
1≤N,W,Q≤1051≤N,W,Q≤105
1≤pw,ai≤W1≤pw,ai≤W
0≤dw≤W−pw0≤dw≤W−pwOutputFor each query, output one integer denotes the minimum number of rows.
Sample Input
2
2 7 4 3
1 3
3
1 2
2 2
5 2
3 8 2 3
1 1 3
1
1 1
Sample Output
2
3
3
1 题解:
这个题目,的确,第一眼看上去是在倍增什么呢?可以倍增字节,但是复杂度还是不对,那么还有什么量可以倍增呢?就只剩下行数了,好久没有写倍增了,什么边界处理什么的都忘了,所以讲一下实现吧。
dp[i][j]表示在没有图的情况下以第i个单词为开头,覆盖2^j次方单词包括i在内需要几个,这个初始状态就是对于每个单词,暴力匹配他还需要多少单词,付给dp[i][0],然后有一个显然的状态转移dp[i][j]=dp[i][j-1]+dp[i+dp[i][j-1]][j-1];
这里处理一下边界,如果dp[i][j-1]||dp[i+dp[i][j-1]][j-1]==0就不处理,保证之后单词数不够的情况下,dp[i][j]=0。
然后再次设一个状态dp2[i][j]表示在有图的情况下以第i个单词为开头,覆盖2^j次方单词包括i在内需要几个,初始值和状态转移都是一样的。求的时候因为不可能超过20,就从20for到0,能跳就跳就可以了。
具体就是没到图的开头时用dp1跳到图的开头,然后用dp2,跳过图中,最后如果还剩下单词就继续用dp跳,有细节,推荐看一下代码。 代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 101000
using namespace std;
int dp[MAXN][],dp2[MAXN][];
int hi[MAXN],star[MAXN];
int a[MAXN];
int n,w,pw,dw,q; void init(){
scanf("%d%d%d%d",&n,&w,&pw,&dw);
memset(a,,sizeof(a));
for(int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);
memset(star,,sizeof(star));
memset(hi,,sizeof(hi));
for(int i=;i<=q;i++) scanf("%d%d",&star[i],&hi[i]);
} void pre(){
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++){
int sum=a[i],j=i+;
while(sum+a[j]+<=w&&j<=n) sum+=a[j++]+;
dp[i][]=j-i;
}
for(int j=;j<=;j++)
for(int i=;i<=n;i++){
if(!dp[i][j-]||!dp[i+dp[i][j-]][j-]) continue;
dp[i][j]=dp[i][j-]+dp[i+dp[i][j-]][j-];
}
memset(dp2,,sizeof(dp2));
for(int i=;i<=n;i++){
int j=i,flag=,sum=;
while(sum+a[j]+flag<=dw&&j<=n) sum+=a[j++]+flag,flag=;
int k=j;
sum=,flag=;
while(sum+a[k]+flag<=w-pw-dw&&k<=n) sum+=a[k++]+flag,flag=;
dp2[i][]=k-i;
}
for(int j=;j<=;j++)
for(int i=;i<=n;i++){
if(!dp2[i][j-]||!dp2[i+dp2[i][j-]][j-]) continue;
dp2[i][j]=dp2[i][j-]+dp2[i+dp2[i][j-]][j-];
}
} int jump1(int now){
int ans=;
for(int j=;j>=;j--){
if(!dp[now][j]) continue;
if(now+dp[now][j]-<=n){
now+=dp[now][j];
ans+=<<j;
}
}
return ans;
} int jump2(int now,int cen){
for(int j=;j>=;j--){
if(!dp[now][j]) continue;
if((<<j)<=cen){
cen-=(<<j);
now+=dp[now][j];
}
}
return now;
} int jump3(int now,int cen){
for(int j=;j>=;j--){
if(!dp2[now][j]) continue;
if((<<j)<=cen){
cen-=(<<j);
now+=dp2[now][j];
}
}
return now;
} void work(){
for(int i=;i<=q;i++){
int x=star[i],h=hi[i],tmp=jump1();
if(tmp<=x-){
printf("%d\n",tmp+h);
continue;
}
int ans=x+h-,now=jump2(,x-);
now=jump3(now,h);
if(now<=n) ans+=jump1(now);
printf("%d\n",ans);
}
} int main()
{
int t;cin>>t;
while(t--){
init();
pre();
work();
}
return ;
}
Typesetting HDU - 6107的更多相关文章
- HDU 6107 - Typesetting | 2017 Multi-University Training Contest 6
比赛的时候一直念叨链表怎么加速,比完赛吃饭路上突然想到倍增- - /* HDU 6107 - Typesetting [ 尺取法, 倍增 ] | 2017 Multi-University Train ...
- HDU 6107 Typesetting (倍增)
Typesetting Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- HDU 6107 Typesetting
Problem Description Yellowstar is writing an article that contains N words and 1 picture, and the i- ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
随机推荐
- SpringCloud学习笔记(1):Eureka注册中心
简介 Eureka是Netflix开源的基于rest的服务治理方案,分为Server端和Client端,Server端为注册中心,其他微服务通过Client端连接Server端进行服务的注册和发现. ...
- Codeforces1093E_Intersection of Permutations
题意 给定两个排列a和b,两种操作,交换b_i和b_j,询问a[l_a...r_a]和b[l_b...r_b]有多少个数相同. 分析 由于给的是排列,保证b的每个数都有a的对应,构造数组c,c[i]表 ...
- SpringCloud超简单的入门(1)--一些简单的介绍
简介 简单来说,springcloud的就是由一组springboot应用(服务)组成,相互之间通过REST等方式进行通信. 两个springboot应用,其中一个作为服务提供者,一个作为服务消费者, ...
- [0]尝试用Unity3d制作一个王者荣耀(持续更新)->游戏规划
太得闲了于是想写个农药,虽然可能会失败但是还是要试一试. 因为是自学的不是Unity专业的可能表达语言会有些不标准!望见谅! 结构: 以组件式(比如说摇杆控制和玩家部分的编写是分离的,可以自由拼装)作 ...
- Python集训营45天—Day01
目录 1. Python简介 2. 第一个Python程序 3. 知识点梳理 序言:未来是数据的世界,而python 是一门可以高效简洁处理数据的语言,博主打算花45天左右完成python学习的从0到 ...
- 作为一名Android开发者,你有过迷茫吗?
前言 经常听新进的小白问道,Android是不是饱和了?想写一篇关于Android开发者忧虑的文章很久了,今天才提起勇气写.最近不管是在微信.QQ群,还是在各大博客网站,都随处听得到Android开发 ...
- ACM团队周赛题解(3)
940和822两套div.2 老规矩 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e ...
- CentOS7 自定义登录前后欢迎信息
博客地址:http://www.moonxy.com 一.摘要 本人当前使用的是阿里云 ECS 服务器,操作系统为 linux,发行版为 CentOS 7.4.1708.系统默认都已经提供了欢迎信息, ...
- Flink 从 0 到 1 学习 —— 如何自定义 Data Sink ?
前言 前篇文章 <从0到1学习Flink>-- Data Sink 介绍 介绍了 Flink Data Sink,也介绍了 Flink 自带的 Sink,那么如何自定义自己的 Sink 呢 ...
- Java中常用IO流之文件流的基本使用姿势
所谓的 IO 即 Input(输入)/Output(输出) ,当软件与外部资源(例如:网络,数据库,磁盘文件)交互的时候,就会用到 IO 操作.而在IO操作中,最常用的一种方式就是流,也被称为IO流. ...