长沙理工大学oj 1486: 文本整齐度 哈理工 1476(dp)

http://www.acmore.net/problem.php?id=1486

1486: 文本整齐度

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 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;
}

posted @ 2013-04-11 22:28  crazy_apple  阅读(501)  评论(0编辑  收藏  举报