codevs 1300:文件排版(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.
当然,这必须对难看程度进行量化。因此我们必须给出单词之间的空格的难看程度,一个包含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)的更多相关文章
- codevs[1300]文件排版
Description 写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序. 完成这个任务最简单的办法是在 ...
- 文件排版(codevs 1300)
题目描述 Description 写电子邮件是有趣的,但不幸的是经常写不好看,主要是因为所有的行不一样长,你的上司想要发排版精美的电子邮件,你的任务是为他编写一个电子邮件排版程序. 完成这个任务最简单 ...
- codevs 1060 搞笑运动会 dp
1060 搞笑世界杯 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codevs.cn/problem/1060/ Description ...
- HDU 1300 Pearls (DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1300 题目大意:珠宝店有100种不同质量的珍珠,质量越高价钱越高,为了促进销售,每买一种类型的珍珠,要 ...
- codevs 1085 数字游戏 dp或者暴搜
1085 数字游戏 2003年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单 ...
- hdu 1300 Pearls(dp)
Pearls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- codevs 1378选课 树形DP
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],tr[] ...
- codevs 1017 乘积最大 dp
1017 乘积最大 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚 ...
- linux文件操作篇 (四) 目录操作
#include <sys/stat.h>#include <unistd.h>#include <dirent.h> //创建文件夹 路径 掩码 int mkdi ...
随机推荐
- 【模板】有源汇有上下界最大流(网络流)/ZOJ3229
先导知识 无源汇有上下界可行流 题目链接 https://vjudge.net/problem/ZOJ-3229 https://www.luogu.com.cn/problem/P5192 (有改动 ...
- 手淘lib-flexible布局适配方案
前置知识:什么是rem CSS3新增的一个相对单位rem(root em,根em).rem是相对于根节点(或者是html节点).如果根节点设置了font-size:10px;那么font-size:1 ...
- 编译安装redis之快速增加redis节点
#: 下载安装包 [root@localhost ~]# wget http://download.redis.io/releases/redis-4.0.14.tar.gz #:解压 [root@l ...
- C/C++语言结构体指针的使用
C/C++语言结构体指针的使用 主要内容 结构体的使用 - 定义,赋值,结构体指针 结构体作为函数参数的使用 指针的使用 代码内容重点 结构体的使用 - 定义,赋值,结构体指针 结构体作为函数参数的使 ...
- 关于python中显存回收的问题
技术背景 笔者在执行一个Jax的任务中,又发现了一个奇怪的问题,就是明明只分配了很小的矩阵空间,但是在多次的任务执行之后,显存突然就爆了.而且此时已经按照Jax的官方说明配置了XLA_PYTHON_C ...
- UIWindow介绍
1.作为容器,包含app所要显示的所有视图 3.与UIViewController协同工作,方便完成设备方向旋转的支持 1.addSubview 2.rootViewController 三.Wind ...
- 选择…Select…(Power Query 之 M 语言)
选择行: 筛选Table.SelectRows-文本与数值 筛选Table.SelectRows-日期与时间 保留错误行:= Table.SelectRowsWithErrors( 表, {" ...
- 使用.NET 6开发TodoList应用(3)——引入第三方日志库
需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...
- Python基础入门(6)- 面向对象编程
1.初识面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本篇随笔将详细介绍Python的面向对象编程. 如果你以前没有接触过面向对象 ...
- JAVA判断字符串中某个字符存在的个数
/** * 判断字符串中某个字符存在的个数 * @param str1 完整字符串 * @param str2 要统计匹配个数的字符 * @return */ public static int co ...