poj1093
题意:给出一个句子和要求整理后每行包含的字符数,要求将其整理为一种总badness最小的形式。设每个空格长度为n,单个空格的badness计算公式为(n-1)^2。总badness等于所有空格的badness的总和。给出整理后的格式。在badness最小的前提下,在分配一行中的空格时要让前面的空格尽量少。如果一个单词单占一行,badness为500。
分析:动态规划。f[i]表示前i个单词的最小badness是多少。f[i]=f[i-j]+cost(i-j,j);。cost(a,b)表示从单词a+1到单词b的放在一行中最小badness是多少。
并用from[i]存储f[i]是从哪个位置计算得来的值,即最后一次更新f[i]时i-j是几,即f[i]所在行的上一行的最后一个单词是第几个。
我们利用from数组可以求出最佳方案,然后按照题中要求输出即可。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int maxn = ; int n, wordsnum;
string words[maxn];
int sum[maxn];
int f[maxn][maxn];
int from[maxn][maxn]; void turntowords(string st)
{
int i = ; while ()
{
i = ;
while (st[i] != ' ' && i < signed(st.length()))
i++;
words[wordsnum++] = st.substr(, i);
sum[wordsnum] = i + sum[wordsnum - ];
if (i == signed(st.length()))
break;
st.erase(, i);
while (st[] == ' ')
st.erase(, );
}
} void init()
{
string st; wordsnum = ;
memset(sum, , sizeof(sum));
getchar();
while ()
{
getline(cin, st);
if (st == "")
break;
turntowords(st);
}
} int cost(int start, int end)
{
int left, right, tot, len; if (end - start == )
return ;
tot = n - (sum[end] - sum[start]);
len = tot / (end - start - );
left = end - start - - tot % (end - start - );
right = tot % (end - start - );
return left * (len - ) * (len - ) + right * len * len;
} void work()
{
int i, j, k; memset(f, -, sizeof(f));
f[][] = ;
for (i = ; i <= wordsnum; i++)
for (j = ; j <= wordsnum; j++)
for (k = ; k <= j && j - k >= i - && n - (sum[j] - sum[j - k]) >= k - ; k++)
if (f[i - ][j - k] != - && (f[i][j] > f[i - ][j - k] + cost(j - k, j) || f[i][j] == -))
{
f[i][j] = f[i - ][j - k] + cost(j - k, j);
from[i][j] = k;
}
} void printline(int start, int end)
{
int left, tot, len, i, j; if (end - start == )
{
cout << words[start] << endl;
return;
}
tot = n - (sum[end] - sum[start]);
len = tot / (end - start - );
left = end - start - - tot % (end - start - );
for (i = start; i < end - ; i++)
{
cout << words[i];
for (j = ; j < len; j++)
printf(" ");
if (i - start + > left)
printf(" ");
}
cout << words[end - ] << endl;
} void output()
{
int i, best = , besti; for (i = ; i <= wordsnum; i++)
if (f[i][wordsnum] < best && f[i][wordsnum] >= )
{
best = f[i][wordsnum];
besti = i;
}
int line[maxn];
int j = wordsnum;
for (i = besti; i > ; i--)
{
line[i] = from[i][j];
j -= from[i][j];
}
j = ;
for (i = ; i <= besti; i++)
{
printline(j, j + line[i]);
j += line[i];
}
cout << endl;
} int main()
{
//freopen("D:\\t.txt", "r", stdin);
while (cin >> n && n != )
{
init();
work();
output();
}
return ;
}
poj1093的更多相关文章
- DP50题(转)
转自https://www.luogu.org/blog/cccx2016/dp50-ti-ti-hao dp50题: poj1014 poj1015 poj1018 poj1036 poj1038 ...
随机推荐
- C语言入门:01.C语言概述
一.计算机和软件常识 1.计算机运行原理 (1)硬件基本组成:硬盘.内存.CPU (2)个部件之间的运作协调(下图)
- [转帖] Linux 创建一个简单的私有CA、发证、吊销证书
原创帖子地址: https://blog.csdn.net/mr_rsq/article/details/71001810 Linux 创建一个简单的私有CA.发证.吊销证书 2017年04月30 ...
- div文本垂直居中(div text vertical aligan)
.box{ width: 135px;height: 84px;display: block; overflow: hidden; } .container { background:darkcyan ...
- 【BZOJ1559】[JSOI2009]密码(AC自动机,动态规划,搜索)
[BZOJ1559][JSOI2009]密码(AC自动机,动态规划,搜索) 题面 BZOJ 洛谷 题解 首先求方案数显然是构建\(AC\)自动机之后再状压\(dp\),似乎没有什么好讲的. 现在考虑答 ...
- 洛谷 P1457 城堡 The Castle 解题报告
P1457 城堡 The Castle 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张"幸运爱尔兰" ...
- CSS框架960Grid从入门到精通一步登天
http://blog.chinaunix.net/uid-22414998-id-2878529.html 1.什么是CSS框架? CSS框架是一种你能够使用在你的web项目中概念上的结构, ...
- Python 文件解压缩
shutil对压缩包的处理是通过调用zipFile和tarFile两个模块来进行的. import zipfile # zipfile压缩 z = zipfile.ZipFile('ss.zip', ...
- IDE和SDK
像我这种不是专科班出来的,真的很多概念都不太清楚,今天来说说IDE和SDK 简单的来说: IDE(集成开发环境 Integrated Development Environment) 就是我们编写代码 ...
- Java远程访问接口的几种方式
一.Java访问远程url接口并获取结果 1.原生JavaAPI获取 package com.util; import java.io.DataOutputStream; import java.io ...
- [应用篇]第二篇 JSP自带标签介绍
JSP 有以下三类标签: 指令:JSP Directive 指令标签用于设置与整个 JSP 页面相关的属性,非常常用. 下面的三种标签是我们使用频率最高的 标签 jsp标签 描述 <%@ pag ...