题目描述

写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序。

完成这个任务最简单的办法是在太短的行中的单词之间插入空格,但这并不是最好的方法,考虑如下例子:

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.

当然,这必须对难看程度进行量化。因此我们必须给出单词之间的空格的难看程度,一个包含NNN个空格符的空白段,其难看程度值为(n−1)2(n-1)^2(n−1)2,程序的目的是使难看程度的总和最小化。例如,第一个例子的难看程度是1+7×7=501+7\times7=501+7×7=50,而第二个例子的难看程度仅为1+1+1+4+1+4=121+1+1+4+1+4=121+1+1+4+1+4=12。

输出时,每一行的开头和结尾处都必须是一个单词,即每行开头和结尾处不能有空白。唯一例外的是该行仅有一个单词组成的情况,对于这种情况你可将单词放在该行开头处输出,此时如果该单词比该行应有的长度短则我们指定它的最坏程度为500500500,当然在这种情况下,该行的实际长度即为该单词的长度。

输入描述

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

输出描述

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

样例输入

28
This is the example you are actually considering.

样例输出

Minimal badness is 12.

Solve

二维的DP:

状态dp[i][j]dp[i][j]dp[i][j]表示第iii个单词末尾放在jjj位置的最小难看程度

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e3+10;
const int mod=1e9+7;
using namespace std;
char ch[maxn];
// dp[i][j]表示第i个单词末尾放到位置j的最小难看程度
int dp[maxn][maxn];
int len[maxn];
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
int cnt=0;
while(cin>>ch)
len[++cnt]=strlen(ch);
ms(dp,INF);
dp[1][n]=500;
dp[1][len[1]]=0;
for(int i=2;i<=cnt;i++)
for(int j=len[i];j<=n;j++)
{
int res=j-len[i];
// 如果是某行的第一个单词,继承上一行的最后一个状态
if(!res)
dp[i][j]=dp[i-1][n];
else
{
if(j==n)
dp[i][j]=dp[i-1][j]+500;
for(int k=0;k<res;k++)
dp[i][j]=min(dp[i][j],dp[i-1][k]+(res-k-1)*(res-k-1));
}
}
cout<<"Minimal badness is "<<dp[cnt][n]<<"."<<endl;
return 0;
}

一维的DP

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
char ch[maxn];
// dp[i]表示以第i个单词作为一行的结尾的最小难看程度
// dp[i]=min(dp[i]+cost(j,i))
// cost(j,i)表示j+1到i在同一行的最小难看程度
// 当空格在一行内平分的时候难看程度最小
int dp[maxn];
int len[maxn];
inline int calc(int l,int r,int n)
{
if(l==r)
{
if(len[r]-len[l-1]==n)
return 0;
return 500;
}
// 一行内的空格数
int res=n-(len[r]-len[l-1]);
// 一行内至少要有r-l个空格】
if(res<r-l)
return INF;
// 将空格平分
int space=res/(r-l);
// 多余的空格往之前的空格段中平分,每段至多一个
int more=res%(r-l);
space-=1;
return space*space*(r-l)+more*(space*2+1);
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
int cnt=0;
cin>>n;
while(cin>>ch)
len[++cnt]=len[cnt-1]+strlen(ch);
ms(dp,INF);
dp[0]=0;
for(int i=1;i<=cnt;i++)
for(int j=1;j<=i;j++)
dp[i]=min(dp[i],dp[j-1]+calc(j,i,n));
cout<<"Minimal badness is "<<dp[cnt]<<"."<<endl;
return 0;
}

codevs 1300:文件排版(DP)的更多相关文章

  1. codevs[1300]文件排版

    Description 写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序. 完成这个任务最简单的办法是在 ...

  2. 文件排版(codevs 1300)

    题目描述 Description 写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序. 完成这个任务最简单 ...

  3. codevs 1060 搞笑运动会 dp

    1060 搞笑世界杯 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codevs.cn/problem/1060/ Description ...

  4. HDU 1300 Pearls (DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1300 题目大意:珠宝店有100种不同质量的珍珠,质量越高价钱越高,为了促进销售,每买一种类型的珍珠,要 ...

  5. codevs 1085 数字游戏 dp或者暴搜

    1085 数字游戏 2003年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB     题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单 ...

  6. hdu 1300 Pearls(dp)

    Pearls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  7. codevs 1378选课 树形DP

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],tr[] ...

  8. codevs 1017 乘积最大 dp

    1017 乘积最大 时间限制: 1 s 空间限制: 128000 KB         题目描述 Description 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚 ...

  9. linux文件操作篇 (四) 目录操作

    #include <sys/stat.h>#include <unistd.h>#include <dirent.h> //创建文件夹 路径 掩码 int mkdi ...

随机推荐

  1. 关于JSONObject的性能问题

    现有一段代码: private JSONObject override(User user, UserVO vo) { String json = JSON.toJSONString(vo); JSO ...

  2. 日常Java 2021/11/2

    Java提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信息和存储在对象中数据的类型.将序列化对象写入文件之后,可以从文件中读取出来 ...

  3. Spark基础:(三)Spark 键值对操作

    1.pair RDD的简介 Spark为包含键值对类型的RDD提供了一些专有的操作,这些RDD就被称为pair RDD 那么如何创建pair RDD呢? 在不同的语言中有着不同的创建方式 在pytho ...

  4. Linux系统中安装软件方法总结

    Linux系统中安装软件方法总结 [1]Linux系统中安装软件的几种方式 [2] Linux配置yum源(本地源和网络源) [3] SuSE下zypper源配置 [4] SUSE zypper 本地 ...

  5. 100个Shell脚本——【脚本2】截取字符串

    [脚本2]截取字符串 一.脚本 现有一个字符串如下: http://www.aaa.com/root/123.htm 请根据以下要求截取出字符串中的字符: 1.取出www.aaa.com/root/1 ...

  6. 【Linux】【Shell】【Basic】条件测试

    1. 数值测试:数值比较 -eq:是否等于: [ $num1 -eq $num2 ] -ne:是否不等于: -gt:是否大于: -ge:是否大于等于: -lt:是否小于: -le:是否小于等于: 2. ...

  7. 【Linux】【Services】【SaaS】Docker+kubernetes(1. 基础概念与架构图)

    1.简介 1.1.  背景:公司正在进行敏捷开发环境的搭建,以取代传统的架构,好处大大的,我就不赘述了.公司原来负责这个项目的同事要转组,我只好交给另外同事继续,但是为了防止同样的事情,我也需要深入了 ...

  8. 【Matlab】向图像域添加噪声/高斯/均匀/伽马/指数/椒盐

    [向图像域添加噪声] matlab自带一个函数:imnoise,可以对图像添加噪声. Matlab的说明 https://www.mathworks.com/help/images/ref/imnoi ...

  9. 阿里云发布CloudOps白皮书,ECS自动化运维套件新升级

    12月10 日,2021云上架构与运维峰会上,阿里云发布业界首部<云上自动化运维白皮书>(简称CloudOps白皮书),并在其中提出了CloudOps成熟度模型.同时,阿里云还宣布了ECS ...

  10. 热部署详细步骤---·> 小热身!

    IDEA 2018.1.5 4版本 热部署 网址:https://www.jb51.net/softjc/629271.html