http://www.acmore.net/problem.php?id=1486
1486: 文本整齐度
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 33 Solved: 9
Description
假设正文是n个长度分别为L1、L2、……、Ln(以字符个数度量,不计空白子字符)的单词构成的序列。我们希望将这个段落在一些行上整齐地打印出来,每行至多M个字符。“整齐度”的标准如下:如果某一行包含从i到j的单词(i<=j),且单词之间只留一个空格,则在行末多余的空格字符个数为 M - (j-i) - (Li+ …… + Lj),它必须是非负值才能让该行容纳这些单词。我们希望所有行(除最后一行)的行末多余空格字符个数的立方和最小,这个立方和就是“整齐度”。
Input
多组测试数据,每组测试数据有两行。
第一行为两个整数n, m,n(1<=n<=2000)表示单词个数, m(1<=m<=500)表示每行最多的字符数。
第二行为正文的n个单词的长度Li(1<=Li<=m),它们按在正文出出现的顺序给出。
Output
每组测试输出一行,包含一个整数,表示最优整齐度。
Sample Input
5 5 4 1 1 3 3 5 6 1 3 3 2 3
Sample Output
17 1
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n,M;
__int64 l[2010],d[2010],s[2010];
__int64 min(__int64 a,__int64 b){return a<b?a:b;}
int main(){
while(scanf("%d%d",&n,&M)!=EOF)
{
int i,j;
s[0] = 0;
for(i = 1; i <= n; i++)
{
scanf("%I64d",&l[i]);
s[i] = s[i-1]+l[i];
}
memset(d,-1,sizeof(d));
d[0] = 0;
for(i = 1; i <= n; i++)
for(j = 0; j < i; j++)
{
if(d[j]==-1)
continue;
int tmp = M-(i-j-1)-(s[i]-s[j]);
if(tmp >= 0)
{
if(i == n)
{
if(d[i]==-1)
d[i] = d[j];
else
d[i] = min(d[i],d[j]);
}
if(d[i]==-1)
d[i] = d[j]+tmp*tmp*tmp;
else
d[i] = min(d[i],d[j]+tmp*tmp*tmp);
}
}
printf("%I64d\n",d[n]);
}
return 0;
}