整齐打印
参考 http://blog.csdn.net/wenlei_zhouwl/article/details/5992367
问题: 考虑在一个打印机上整齐地打印一段文章的问题。输入的正文是n个长度分别为L1、L2、……、Ln(以字符个数度量)的单词构成的序列。我们希望将这个段落在一些行上整齐地打印出来,每行至多M个字符。“整齐度”的标准如下:如果某一行包含从i到j的单词(i<j),且单词之间只留一个空格,则在行末多余的空格字符个数为 M - (j-i) - (Li+ …… + Lj),它必须是非负值才能让该行容纳这些单词。我们希望所有行(除最后一行)的行末多余空格字符个数的立方和最小。请给出一个动态规划的算法,来在打印机整齐地打印一段又n个单词的文章。分析所给算法的执行时间和空间需求。
分析:
构建数组a[i]代表包含1->i单词的最优“整齐度”——空格的立方总和。开始时,令a[0]=0。a[i]的递推式如下
W[k][i]代表将k到i的单词写入一行时,该行的多余空格数的立方。
每次计算a[i]时,循环k从i-1开始,直到某个k值使得
值为负,则跳出。
最终a[n]即为所求的最小立方总和。
程序:
#include<iostream>
#include<string>
#include<cstring>
#include<cstdlib>
#include<climits>
using namespace std;
int main(void)
{
void zq_print(void);
zq_print();
return 0;
}
void zq_print(void)
{
//输入数据
int num,M,count;
int p,q,i,j,flag;
cin>>num;
cin>>M;
string* data=new string[num];
for(i=0;i<num;i++)
{
cin>>data[i];
}
int *line=new int[num]();
int *c=new int[num];
memset(c,0,num);
p=0;flag=0;q=0;count=0;
while(p<num)
{
line[q]=INT_MAX;
for(i=p;i<num;)
{
/*计算的累加值*/
int sum=0;
for(j=p;j<=i;j++)
sum+=data[j].size();
//计算3次方
int temp=(M-i+p-sum)*(M-i+p-sum)*(M-i+p-sum);
if(q>=1)
temp+=line[q-1];
if(temp>=0 && (temp<line[q]))
{
flag=i;
c[q]=flag;
line[q]=temp;
i++;
}
else
break;
//现在判断flag的值,是不是到达最后一行
}
++q;
++count;
if(flag==num-1)
break;
else
p=flag+1;
}
cout<<"count="<<count<<endl;
for(i=0;i<count;i++)
{
cout<<c[i]<<"--->"<<line[i]<<endl;
}
//共count行
for(i=0;i<count;i++)
{
int begin=0;
if(i>0)
begin=c[i-1]+1;
for(j=begin;j<=c[i];++j)
cout<<data[j]<<" ";
cout<<endl;
}
delete [] c;
delete [] line;
delete [] data;
}
浙公网安备 33010602011771号