题目链接:http://poj.org/problem?id=3390
题意:给出n个单词,每个单词有固定的长度,按顺序分行输出这些单词,每行的长度不超过m(单词间包括空格,空格长度不忽略),求每行get=(m-len)*(m-len)的和最小。
分析:f[i]表示前i个单词放好之后的最小值,对于新放入第i个,去i之前的j个单词组成新的一行,使f[i-j]+get(i,j)最小。枚举j更新答案即可。
附代码:
View Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define MaxN 10010
#define get(x) (m-x)*(m-x)
#define a(i) (sum[i]-sum[i-1])
int n,m;
int f[MaxN],sum[MaxN];
int main()
{
freopen("1.in","r",stdin);
freopen("out","w",stdout);
int Case,x;
scanf("%d",&Case);
while (Case--)
{
memset(f,0,sizeof(f));
memset(sum,0,sizeof(sum));
scanf("%d%d",&m,&n);
for (int i=1;i<=n;i++)
scanf("%d",&x),
sum[i]=sum[i-1]+x;
for (int i=1;i<=n;i++)
{
int temp=a(i);
f[i]=f[i-1]+get(temp);
for (int j=i-1;j>0;j--)
{
if (temp+a(j)+1<=m)
{
int y=temp+a(j)+1;
f[i]=min(f[i],f[j-1]+get(y));
temp=y;
} else break;
}
}
printf("%d\n",f[n]);
}
return 0;
}
后记:题目比较水,不过由于把j写成i白调了半天,甚至以为自己的想法是错的...粗心害死人啊...