HDU 6107 Typesetting (倍增)
Posted 贱人方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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-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.
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.
Input
The 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 ai, indicates i-th word consists of ai 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≤10
1≤N,W,Q≤105
1≤pw,ai≤W
0≤dw≤W−pw
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 ai, indicates i-th word consists of ai 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≤10
1≤N,W,Q≤105
1≤pw,ai≤W
0≤dw≤W−pw
Output
For 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
【题意】一张纸上写了些单词,每个单词处于同一行,不被分开,且两个单词之间有一个空格或换行。现在要在照片中 插入一张宽度固定的图片。Q次询问,问你当照片插进单词中,单词总共占据多少行。
【分析】先对于三种宽度w,dw,w-dw-pw,预处理 当第i个单词放在当前宽度最左端时,下一行第一个单词是哪个,h[i]表示第i个单词放在首端时剩下的需要占据多少行。然后倍增,s[i][j]表示在没有图片区域第i个单词放在最左端时,往下2^j行的第一个单词是哪个,然后t数组表示插入单词的区域。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define mp make_pair #define rep(i,l,r) for(int i=(l);i<=(r);++i) #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 1e5+5;; const int M = 17; const int mod = 1e9+7; const int mo=123; const double pi= acos(-1.0); typedef pair<int,int>pii; int n,w,q,pw,dw; int a[N],lto[N],rto[N]; int h[N],s[N][M],t[N][M]; void solve(int len,int to[]){ for(int i=0,j=0,x=-1;i<=n;i++){ while(x+a[j]+1<=len)x+=a[j++]+1; to[i]=j;x-=a[i]+1; } } int main() { int T; scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&n,&w,&pw,&dw); rep(i,0,n-1)scanf("%d",&a[i]); a[n]=w+5; solve(w,lto); rep(i,0,n)s[i][0]=lto[i]; rep(j,1,M-1)rep(i,0,n)s[i][j]=s[s[i][j-1]][j-1]; h[n]=0; for(int i=n-1;i>=0;i--)h[i]=h[lto[i]]+1; solve(dw,lto);solve(w-dw-pw,rto); rep(i,0,n)t[i][0]=rto[lto[i]]; rep(j,1,M-1)rep(i,0,n)t[i][j]=t[t[i][j-1]][j-1]; scanf("%d",&q); while(q--){ int x,hh,res=0; scanf("%d%d",&x,&hh); int ans=0; ans+=min(--x,h[0]); rep(j,0,M-1)if(x>>j & 1)res=s[res][j]; rep(j,0,M-1)if(hh>>j & 1)res=t[res][j]; ans+=hh+h[res]; printf("%d\n",ans); } } return 0; }
以上是关于HDU 6107 Typesetting (倍增)的主要内容,如果未能解决你的问题,请参考以下文章