题意:给出一个句子和要求整理后每行包含的字符数,要求将其整理为一种总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的更多相关文章

  1. DP50题(转)

    转自https://www.luogu.org/blog/cccx2016/dp50-ti-ti-hao dp50题: poj1014 poj1015 poj1018 poj1036 poj1038 ...

随机推荐

  1. File类操作文件

    简单示例: public static void main(String[] args) { // 列出系统所有的根路径 File[] listRoots = File.listRoots(); fo ...

  2. node之post提交上传

    post文件上传 multer 中间件 在node中 express为了性能考虑采用按需加载的方式,引入各种中间件来完成需求, 平时解析post上传数据时候,是用body-parse.但这个中间件有缺 ...

  3. Spring MVC的路径匹配规则 Ant-style

    Spring默认的策略实现了 org.springframework.util.AntPathMatcher,即Apache Ant的样式路径,Apache Ant样式的路径有三种通配符匹配方法(在下 ...

  4. Spring之注入复杂类型属性

    注入类: package helloworld; import java.util.List; import java.util.Map; import java.util.Properties; p ...

  5. Spring之使用表达式配置切入点

    使用表达式配置切入点

  6. 页面用一个遮罩层显示加载,加载完后隐藏该div

    <div id="background" class="background" style="display: none; "> ...

  7. swagger error: Conflicting schemaIds: Duplicate schemaIds detected for types A and B

    使用Web API并使用swashbuckle生成swagger文档,我在两个不同的命名空间中定义了两个具有相同名称的不同类.当我在浏览器中打开swagger页面时,它说: Conflicting s ...

  8. BZOJ2458 Beijing2011最小三角形(分治)

    类似于平面最近点对,考虑分治,即分别计算分割线两侧的最小三角形再考虑跨过线的三角形. 复杂度证明也是类似的,对于某一个点,在另一侧可能与其构成最小三角形的点在一个d*d/2的矩形内(两边之和大于第三边 ...

  9. 洛谷 P4112 [HEOI2015]最短不公共子串 解题报告

    P4112 [HEOI2015]最短不公共子串 题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的"子串"指的是它的连续的一段,例如bcd是 ...

  10. CRT && exCRT模板

    CRT从各种方面上都吊打exCRT啊...... 短,好理解... 考虑构造bi使得bi % pi = ai,bi % pj = 0.然后全加起来就行了. 显然bi的构造就是ai * (P/pi) * ...