整齐打印

参考 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;
}

  

posted on 2013-06-20 15:14  紫金树下  阅读(478)  评论(0编辑  收藏  举报