題目鏈接
http://codeforces.com/gym/100917/problem/D
problem description
Famous Berland coder and IT manager Linus Gates announced his next proprietary open-source system "Winux 10.04 LTS"
In this system command "dir -C" prints list of all files in the current catalog in multicolumn mode.
Lets define the multicolumn mode for number of lines l. Assume that filenames are already sorted lexicographically.
Example of multi-column output:
a accd e t
aba b f wtrt
abacaba db k
In the example above width of output is equal to 19.
"dir -C" command selects minimal l, such that width of the output does not exceed width of screen w.
Given information about filename lengths and width of screen, calculate number of lines l printed by "dir -C" command.
InputFirst line of the input contains two integers n and w — number of files in the list and width of screen (1 ≤ n ≤ 105, 1 ≤ w ≤ 109).
Second line contains n integers fi — lengths of filenames. i-th of those integers represents length of i-th filename in the lexicographically ordered list (1 ≤ fi ≤ w).
OutputPrint one integer — number of lines l, printed by "dir -C" command.
Examples input11 20output
1 3 7 4 1 2 1 1 1 1 4
3
題意:有n個目錄名字符串,長度為a[1]~a[n] 屏幕寬為w ,現在要按照已經給的目錄循序一列一列的放,每一列放x個,最後一列放<=x個 要求每一列目錄名左端對整齊 ,形成一個長方形的塊 ,且塊與塊之間空一格,且不能超過屏幕的寬度,求最小的行數;
思路:先對輸入長度處理,用ST算出每個區間的最大值,然後枚舉行數x 從1 ~ n;
代碼如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <map> #include <cmath> using namespace std; typedef long long LL; const int MAXN = 1e5+5; int a[MAXN],m[30][MAXN]; int n; LL w; int main() { while(scanf("%d%I64d",&n,&w)!=EOF) { memset(m,0,sizeof(m)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); m[0][i]=a[i]; } for(int i=1;i<=(int)log(n)/log(2);i++) { for(int j=1;j+(1<<i)-1<=n;j++) m[i][j]=max(m[i-1][j],m[i-1][j+(1<<(i-1))]); } for(int i=1;i<=n;i++) { int k=(int)log(i); long long sum=0; for(int j=0;j<n/i;j++) { sum+=(long long)max(m[k][j*i+1],m[k][i*(j+1)-(1<<k)+1])+1; } if(n%i!=0) { k=(int)log(n%i); sum+=(long long)max(m[k][n-n%i+1],m[k][n-(1<<k)+1])+1; } if(sum-1<=w){ printf("%d\n",i); break; } } } return 0; }