uva live 6190 Beautiful Spacing (二分法+dp试 基于优化的独特性质)

I - Beautiful Spacing

Time Limit:8000MS     Memory Limit:65536KB     64bit IO Format:%lld
& %llu

Submit cid=57803#status//I/0" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" style="font-family:Verdana,Arial,sans-serif; font-size:1em; border:1px solid rgb(211,211,211); background-color:rgb(227,228,248); color:rgb(85,85,85); display:inline-block; position:relative; padding:0px; margin-right:0.1em; zoom:1; overflow:visible; text-decoration:none">Status

Description

Text is a sequence of words, and a word consists of characters. Your task is to put words into a grid with W columns and sufficiently many lines. For the beauty of the layout, the following conditions have to be satisfied.

  1. The words in the text must be placed keeping their original order. The following figures show correct and incorrect layout examples for a 4 word text "This is a pen" into 11 columns.


    Figure I.1: A good layout.


    Figure I.2: BAD | Do not reorder words.

  2. Between two words adjacent in the same line, you must place at least one space character. You sometimes have to put more than one space in order to meet other conditions.

    Figure I.3: BAD | Words must be separated by spaces.

  3. A word must occupy the same number of consecutive columns as the number of characters in it. You cannot break a single word into two or more by breaking it into lines or by inserting spaces.

    Figure I.4: BAD | Characters in a single word must be contiguous.

  4. The text must be justified to the both sides. That is, the first word of a line must startfrom the first column of the line, and except the last line, the last word of a line must end at the last column.

    Figure I.5: BAD | Lines must be justi ed to both the left and the right sides.

The text is the most beautifully laid out when there is no unnecessarily long spaces. For instance, the layout in Figure I.6 has at most 2 contiguous spaces, which is more beautiful than that in Figure I.1, having 3 contiguous spaces. Given an input text
and the number of columns, please find a layout such that the length of the longest contiguous spaces between words is minimum.

Figure I.6: A good and the most beautiful layout.

Input

The input consists of multiple datasets, each in the following format.

W N

x1x2 ... xN

WN, and xi are all integers. W is the number of columns (3 ≤ W ≤ 80,000). N is the number of words (2 ≤ N ≤ 50,000). xi is the number of characters in the i-th
word (1 ≤ xi ≤ (W?1)/2 ). Note that the upper bound on xi assures that there always exists a layout satisfying the conditions.

The last dataset is followed by a line containing two zeros.

Output

For each dataset, print the smallest possible number of the longest contiguous spaces between words.

Sample Input

11 4
4 2 1 3
5 7
1 1 1 2 2 1 2
11 7
3 1 3 1 3 3 4
100 3
30 30 39
30 3
2 5 3
0 0

Output for the Sample Input

2
1
2
40
1

题意:给你一个含n个单词的文本。依照一些规则放入宽度为w的矩形中,如何使最大的空格最小。

思路:答案是单调的,二分答案,然后用dp来检验,dp[i]表示第i个单词是否能结尾,easy想到的是n^2检验,可是肯定会TLE的,须要优化。能够发现假设i-j能够放在一行,可是最大空格会超过mid,那么i+1-j也不行,假设用i来推的时候能够推到[s,t]能够,那么下次就能够直接从t+1開始了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 50005
#define MAXN 200005
#define mod 1000000007
#define INF 0x3f3f3f3f
#define eps 1e-6
const double pi=acos(-1.0);
typedef long long ll;
using namespace std;

int n,w;
int len[maxn],sum[maxn];
bool dp[maxn];

bool isok(int mid)
{
    int i,j,last=0;
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    if(sum[n]+n-1<=w) return true ;
    for(i=0; i<n-1; i++)
    {
        if(!dp[i]) continue ;
        for(j=max(i+2,last+1); j<=n; j++)
        {
            if(w<sum[j]-sum[i]+j-i-1) break ;
            if(w>sum[j]-sum[i]+ll(j-i-1)*mid) continue ;
            last=j;
            dp[j]=1;
            if(sum[n]-sum[j]+n-j-1<=w) return true ;
        }
    }
    return false ;
}
void solve()
{
    int i,j,le=1,ri=w,mid,ans;
    while(le<=ri)
    {
        mid=(le+ri)>>1;
        if(isok(mid))
        {
            ans=mid;
            ri=mid-1;
        }
        else le=mid+1;
    }
    printf("%d\n",ans);
}
int main()
{
    int i,j;
    while(~scanf("%d%d",&w,&n))
    {
        if(w==0&&n==0) break ;
        sum[0]=0;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&len[i]);
            sum[i]=sum[i-1]+len[i];
        }
        solve();
    }
    return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-27 07:16:17

uva live 6190 Beautiful Spacing (二分法+dp试 基于优化的独特性质)的相关文章

uva live 6190 Beautiful Spacing (二分+dp检验 根据特有性质优化)

I - Beautiful Spacing Time Limit:8000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Text is a sequence of words, and a word consists of characters. Your task is to put words into a grid with W columns and suffic

【BZOJ-4692】Beautiful Spacing 二分答案 + 乱搞(DP?)

4692: Beautiful Spacing Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 46  Solved: 21[Submit][Status][Discuss] Description 文章是一些单词组成的序列,单词由字母组成.你的任务是将一篇文章的单词填充到一个网格中,其中网格包含W列和足够多的行.为了布局之美,以下限制都需要满足. 1.文章中的文字需要按照原有的顺序放置.下图表示了将4个单词的文章“This is a pen”放入

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <

UVA - 825Walking on the Safe Side(dp)

题目: UVA - 825Walking on the Safe Side(dp) 题目大意:给出一个n * m的矩阵,起点是1 * 1,终点是n * m,这个矩阵上有些点是不可以经过的,要求从起点到终点距离最短,并且不能走那种不能走的点,一共有多少种方式. 解题思路:要求路径最短的话,每个点要不向右走,要不向下走.dp[i][j] = dp[i][j + 1] + dp[i + 1][j]:当这个点不能通过,dp[i][j] = 0:这个坑点在样例输入,不一定是规范的输入,可能两个数字之间很多

uva 11361 Investigating Div-Sum Property 数位dp

// uva 11361 Investigating Div-Sum Property 数位dp // // 题目大意: // // 给你一个整数a和一个整数b,问在[a,b]范围内,有多少个自身被k整除并且 // 各位数之和也能被k整除.比如k = 7 ,322满足条件,因为332能被整除7,并 // 3 + 2 + 2 = 7 也能被7整除 // // 解题思路: // // 求一个区间的题目,这类题目,往往可以转化为不超过x的f(x).则最后要求 // 的就是f(b) - f(a-1).如

uva live 3516 Exploring Pyramids 区间DP

// uva live 3516 Exploring Pyramids 区间DP // // 题目大意: // // 给你一个多叉树,每个节点是一个大写字母,从根节点走,按照先序遍历的 // 原则访问,不能访问则回溯,每次记录一下节点的字符,最后得到一个字符串.现 // 在给你一个字符串,问可能符合条件的多叉树的数量. // // 解题思路: // // 区间DP,我们注意到,从根节点出发,一定会再次回到根节点,那么我们可以设 // d(i,j) 是序列i到j段形成的符合条件的多叉树的数量,则

UVA 11825 Hackers&#39; Crackdown 状压DP

感觉白书上的做法很神! 首先状压表示电脑之间的联通关系,然后预处理出所有关闭电脑的组合达到的状态,然后枚举每个状态并且枚举每个状态的所有子集,之后无脑递推就木有了. 关于枚举一个状态所有子集的小技巧:假设当前状态是S0 有 for s = s0; s != 0; s =  (s - 1) & s0 #include <cstdio> #include <cstring> #include <iostream> #include <map> #incl

UVA 10453 Make Palindrome(区间简单DP)

题意:给出一个字符串A,求出需要至少插入多少个字符使得这个字符串变成回文串. 思路:设dp[i][j]为使区间[i, j]变成回文串所需要的最少字符个数. 1.A[i] == A[j的情况]那么dp[i][j] = min(dp[i][j], dp[i + 1][j -1]); 2.或者在第j个位置插入一个字符A[i], dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); 3.或者在第i个位置插入一个字符A[j], dp[i][j] = min(dp[i][j

uva 10712 - Count the Numbers(数位dp)

题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a,b:问说在a到b之间有多少个n. 解题思路:数位dp,dp[i][j][x][y]表示第i位为j的时候,x是否前面是相等的,y是否已经出现过n.对于n=0的情况要特殊处理前导0,写的非常乱,搓死. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using na