H - Typesetting HDU - 6107

Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains aiaicharacters. 
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][22],dp2[MAXN][22];
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,0,sizeof(a));
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    scanf("%d",&q);
    memset(star,0,sizeof(star));
    memset(hi,0,sizeof(hi));
    for(int i=1;i<=q;i++) scanf("%d%d",&star[i],&hi[i]);
}

void pre(){
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++){
        int sum=a[i],j=i+1;
    while(sum+a[j]+1<=w&&j<=n) sum+=a[j++]+1;
        dp[i][0]=j-i;
    }
    for(int j=1;j<=20;j++)
        for(int i=1;i<=n;i++){
            if(!dp[i][j-1]||!dp[i+dp[i][j-1]][j-1]) continue;
            dp[i][j]=dp[i][j-1]+dp[i+dp[i][j-1]][j-1];
        }
    memset(dp2,0,sizeof(dp2));
    for(int i=1;i<=n;i++){
        int j=i,flag=0,sum=0;
        while(sum+a[j]+flag<=dw&&j<=n) sum+=a[j++]+flag,flag=1;
        int k=j;
        sum=0,flag=0;
        while(sum+a[k]+flag<=w-pw-dw&&k<=n) sum+=a[k++]+flag,flag=1;
        dp2[i][0]=k-i;
    }
    for(int j=1;j<=20;j++)
        for(int i=1;i<=n;i++){
            if(!dp2[i][j-1]||!dp2[i+dp2[i][j-1]][j-1]) continue;
            dp2[i][j]=dp2[i][j-1]+dp2[i+dp2[i][j-1]][j-1];
        }
}

int jump1(int now){
    int ans=0;
    for(int j=20;j>=0;j--){
        if(!dp[now][j]) continue;
        if(now+dp[now][j]-1<=n){
            now+=dp[now][j];
            ans+=1<<j;
        }
    }
    return ans;
}

int jump2(int now,int cen){
    for(int j=20;j>=0;j--){
        if(!dp[now][j]) continue;
        if((1<<j)<=cen){
            cen-=(1<<j);
            now+=dp[now][j];
        }
    }
    return now;
}

int jump3(int now,int cen){
    for(int j=20;j>=0;j--){
        if(!dp2[now][j]) continue;
        if((1<<j)<=cen){
            cen-=(1<<j);
            now+=dp2[now][j];
        }
    }
    return now;
}

void work(){
    for(int i=1;i<=q;i++){
        int x=star[i],h=hi[i],tmp=jump1(1);
        if(tmp<=x-1){
            printf("%d\n",tmp+h);
            continue;
        }
        int ans=x+h-1,now=jump2(1,x-1);
        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 0;
}
时间: 2024-11-27 18:11:21

H - Typesetting HDU - 6107的相关文章

HDU 6107 Typesetting (倍增)

Typesetting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 144    Accepted Submission(s): 72 Problem Description Yellowstar is writing an article that contains N words and 1 picture, and the i-

HDU 6107 Typesetting 倍增

Typesetting Problem Description Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains ai characters.The page width is fixed to W characters. In order to make the article look more beautiful, Yellowstar has m

H - Tickets HDU 1260 (动态规划)

H - Tickets Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1260 Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this is really a tuff time for Joe who sel

H题 hdu 2520 我是菜鸟,我怕谁

题目大意:http://acm.hdu.edu.cn/showproblem.php?pid=2520 我是菜鸟,我怕谁 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7698    Accepted Submission(s): 4505 Problem Description lin2144是一只小菜鸟,都是笨鸟先飞,lin2144

H - Food - hdu 4292(简单最大流)

题目大意:有N个人,然后有F种食品和D种饮料,每个人都有喜欢的饮料和食品,求出来这些食品最多能满足多少人的需求. 输入描述: 分析:以前是做过类似的题目的,不过输入的信息量比较大,还是使用邻接表的好些,邻接矩阵有可能会TLE,建图如下图流程 不过要注意人需要拆点的,因为一个人只食用一种食品就可以了,所以拆点让他们之间的流量为1.ps:很伤心的这题竟然做了6个小时,算是比较裸的最大流题目....最后终于检查出来错误的位置,dinic里面把while循环写成了if,貌似这是第二次犯这么二缺的事儿了.

2014 HDU多校弟八场H题 【找规律把】

看了解题报告,发现看不懂 QAQ 比较简单的解释是这样的: 可以先暴力下达标,然后会发现当前数 和 上一个数 的差值是一个 固定值, 而且等于当前数与i(第i个数)的商, 于是没有规律的部分暴力解决,有规律的套公式 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring&g

hdu 3687 10 杭州 现场 H - National Day Parade 暴力水题

H - National Day Parade Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3687 Appoint description:  System Crawler  (2014-11-08) Description There are n×n students preparing for the National Day

HDU - 4788 Hard Disk Drive (成都邀请赛H 水题)

HDU - 4788 Hard Disk Drive Time Limit:1000MS   Memory Limit:32768KB   64bit IO Format:%I64d & %I64u [Submit]  [Go Back]  [Status] Description Yesterday your dear cousin Coach Pang gave you a new 100MB hard disk drive (HDD) as a gift because you will

H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)

H - Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4027 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our