zoukankan      html  css  js  c++  java
  • 文件排版,较难的线性dp

    文件排版

    写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序。
    完成这个任务最简单的办法是在太短的行中的单词之间插入空格,但这并不是最好的方法,考虑如下例子:
    ****************************
    This is the example you  are
    actually considering.
    假设我们想将第二行变得和第一行一样长,靠简单地插入空格则我们将得到如下结果:
    ****************************
    This is the example you  are
    actually             considering.

    但这太难看了,因为在第二行中有一个非常大的空白,如果将第一行的单词“are”移到下一行我们将得到较好的结果:
    ****************************
    This  is  the  example   you
    are  actually   considering.

    当然,这必须对难看程度进行量化。因此我们必须给出单词之间的空格的难看程度,一个包含N个空格符的空白段,其难看程度值为(n-1)2,程序的目的是使难看程度的总和最小化。例如,第一个例子的难看程度是1+7*7=50,而第二个例子的难看程度仅为1+1+1+4+1+4=12。
    输出时,每一行的开头和结尾处都必须是一个单词,即每行开头和结尾处不能有空白。唯一例外的是该行仅有一个单词组成的情况,对于这种情况你可将单词放在该行开头处输出,此时如果该单词比该行应有的长度短则我们指定它的最坏程度为500,当然在这种情况下,该行的实际长度即为该单词的长度。

    输入
    输入文件第一行是一个整数N,表示该段要求达到的宽度,1<=N<=80。该段文章由一个或多个单词组成,单词由ASCII码值为33到126(包含33和126)的字符组成,单词与单词之间用空格隔开(可能超过一个)。单词长度不会超过段落要求达到的宽度。一段文字所有单词的总长度不会超过10000个字符,任何一行都不会超过100个字符,任何一个单词都在同一行内。

    输出
    对于每个段落,找出使其难看程度最小的排版形式并输出句子:“Minimal badness is B.”,B是指按可能的最好排版形式会发生的难看程度值。注意排版后文本行数任意,多余的空格也可删除。

    样例
    输入:
    28
    This is the example you  are
    actually considering.

    输出:
    Minimal badness is 12.

    一看到这道题

    设dp(i,j)表示前个单词构成j行的最小丑陋程度

    于是dp(i,j)=min{dp(k,j-1)+丑陋程度(k+1---i)(k为可行解)}

    然而我发现了一个问题:题目中并没有说明要安排多少行所以j并没有必要作为一维;QAQ;

    所以我们新定义一个状态dp(i)表示前i个单词的最小丑陋程度

    于是dp(i)表示前个单词的最小丑陋程度

    dp(i)=min{dp(j)+丑陋程度(j+1--i)}

    答案为dp(单词总数);

    时间复杂度O(n^2)

    空间复杂度O(n)

    时间复杂的还可以进行进一步的优化(省去暴力枚举)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int lim,n,sum[10001],f[10001];
    int calc(int l,int r){
        if(!(l^r)){
            if(!((sum[r]-sum[l-1])^lim))
                return 0;
            return 500;
        }
        int t=lim-sum[r]+sum[l-1];
        if(t<r-l)
            return inf;
        int m=t/(r-l),k=t-m*(r-l);m--;
        return 1LL*m*m*(r-l)+1LL*k*(m<<1|1);
    }
    int main(){
        char ch[101];
        scanf("%d",&lim);
        while(~scanf("%s",ch))
            sum[++n]=sum[n-1]+strlen(ch);
        f[0]=0;
        for(int i=1;i<=n;i++)
            f[i]=inf;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                f[i]=min(f[i],f[j-1]+calc(j,i));
        printf("Minimal badness is %d.
    ",f[n]);
        return 0;
    }
    

      

  • 相关阅读:
    微信小程序 WePY 2 框架入门教程
    微信小程序 WePY 1.7.X 框架入门教程
    /deep/ 深度作用选择器作用及使用
    微信小程序 wx.getUserProfile 接口获取用户信息
    Wepy 微信小程序项目踩坑记
    计算机网络-第一章概述OSI参考模型
    如何安装pycocotools为文件?
    第三章 系统总线
    第二章 计算机的发展和展望
    第一章 计算机基础概论
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7560092.html
Copyright © 2011-2022 走看看