zoukankan      html  css  js  c++  java
  • HDU 6107 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 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.

    题目大意:
    有N个单词,每一个单词长度为(a_i),现在存在一页纸,宽度为W,和一张需要放进纸中的照片,照片的宽度为pw,距离纸的左边x,距离右边W-pw-x,有Q组询问,(x,y)表示照片从第x行开始,长度为y,求把单词和照片都放进纸中,需要占用多少行

    解题报告:
    用时:1h,1WA
    比较简单,直接预处理出:
    (f[i][j])表示在没有照片的行中,从第(i)个单词开始,占用(2^j)行可以放下的单词数
    (g[i][j])表示在有照片的行中,从第(i)个单词开始,占用(2^j)行可以放下的单词数
    我们可以先用二分处理出(f[i][0])(g[i][0])
    显然:
    (f[i][j]=f[i][j-1]+f[i+f[i][j-1]][j-1])
    (g[i][j]=g[i][j-1]+g[i+g[i][j-1]][j-1])
    最后再分照片前的部分,照片的部分,和照片后的三个部分处理即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=1e5+5;
    int n,m,W,pw,lw,rw,a[N],sum[N],f[N][20];
    int g[N][20],maxlen;
    int midit(int sta,int lim){
        if(sta>n || !lim)return 0;
        int l=sta,r=n,mid,ret=l-1;
        while(l<=r){
            mid=(l+r)>>1;
            if(sum[mid]-sum[sta-1]+mid-sta<=lim)
                ret=mid,l=mid+1;
            else r=mid-1;
        }
        return ret-sta+1;
    }
    void prework(){
        int x,y;
        for(int i=1;i<=n;i++){
            f[i][0]=midit(i,W);
            x=midit(i,lw);y=midit(i+x,rw);
            g[i][0]=x+y;
        }
        for(int j=1;j<=maxlen;j++){
            for(int i=1;i<=n;i++){
                if(i+f[i][j-1]<=n)
                    f[i][j]=f[i][j-1]+f[i+f[i][j-1]][j-1];
                else f[i][j]=N;
                if(i+g[i][j-1]<=n)
                    g[i][j]=g[i][j-1]+g[i+g[i][j-1]][j-1];
                else g[i][j]=N;
                if(i+f[i][j]-1>n)f[i][j]=N;
                if(i+g[i][j]-1>n)g[i][j]=N;
            }
        }
    }
    int solve(int s,int d){
        int res=n,x=1,ans=0,tot=s-1;
        for(int i=maxlen;i>=0;i--){
            if(tot>=(1<<i) && res>=f[x][i] && x<=n)
                tot-=(1<<i),res-=f[x][i],x+=f[x][i],ans+=(1<<i);
        }
        int pre=ans+d;
        if(!res)return pre;
        tot=d;
        for(int i=maxlen;i>=0;i--){
            if(tot>=(1<<i) && res>=g[x][i] && x<=n)
                tot-=(1<<i),res-=g[x][i],x+=g[x][i],ans+=(1<<i);
        }
        ans=Max(pre,ans);
        if(!res)return ans;
        for(int i=maxlen;i>=0;i--){
            if(res>=f[x][i] && x<=n)
                res-=f[x][i],x+=f[x][i],ans+=(1<<i);
        }
        return ans;
    }
    void work()
    {
        scanf("%d%d%d%d",&n,&W,&pw,&lw);
        maxlen=log(n)/log(2)+1;rw=W-pw-lw;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
        prework();
        int Q,x,y;cin>>Q;
        while(Q--){
            scanf("%d%d",&x,&y);
            printf("%d
    ",solve(x,y));
        }
    }
    
    int main()
    {
        int T;cin>>T;
        while(T--)work();
        return 0;
    }
    
    
  • 相关阅读:
    mvc razor中renderPartial,RenderAction,Partial,Action的使用选择
    jquery最常用的几个方法。——可删除
    配置文件参数引用
    tinkphp5.0目录结构说明
    ionic ios上状态栏和app重叠解决方案
    cordova-plugin-alipay-v2使用篇(更新至20170725)(亲测可用)
    Ionic2 App Import BrowserAnimationsModule or NoopAnimationsModule问题
    ionic3.0 中带顶部导航的下拉刷新列表的实现
    npm install 时 提示err code EINTEGRITY报错
    ionic3.0 alipay-base插件移除后会添加多余的链接文件在nodes-modules中,导致再安装其他插件或移除插件时报错问题
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7562294.html
Copyright © 2011-2022 走看看