CLRS 15-2 整齐打印

本文介绍了一种使用动态规划解决打印文章整齐布局问题的方法,通过定义状态转移方程来最小化每行空格数的立方和。算法分析了执行时间和空间需求,并提供了关键步骤的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

考虑在一个打印机上整齐地打印一段文章的问题。输入的正文是n个长度分别为L1、L2、……、Ln(以字符个数度量)的单词构成的序列。我们希望将这个段落在一些行上整齐地打印出来,每行至多M个字符。“整齐度”的标准如下:如果某一行包含从i到j的单词(i<j),且单词之间只留一个空格,则在行末多余的空格字符个数为 M - (j-i) - (Li+ …… + Lj),它必须是非负值才能让该行容纳这些单词。我们希望所有行(除最后一行)的行末多余空格字符个数的立方和最小。请给出一个动态规划的算法,来在打印机整齐地打印一段又n个单词的文章。分析所给算法的执行时间和空间需求。

解答:

定义remain[i, j] = M - j + i - ∑lk ,其中k = i, ..., j,表示余下的空格数

定义cube[i, j],表示每行空格数的立方值,MAX表示无穷大

                 |------>MAX                 当remain[i, j] < 0时

cube[i, j] = |------>0                      当j == n,且remain[i, j] >= 0 (其实这里表示的就是最后一行)

                 |------>(remain[i, j])3     非上述两种情况时

定义所有立方之和sum[i],假设sum[j]表示的是1,...,j这j个单词的最优排列(即所求立方和最小),那么在最后一行,假设是i,...,j这些单词,那么sum[j] = sum[i-1] + cube[i, j]。

             |------>0                                                 if j == 0

sum[j] = |

             |------>min(sum[i - 1] + cube[i - 1, j]       if j > 0,其中1 <= i <= j

复制代码
 1 GET-REMAIN()
 2 {
 3   for (i = 1; i <= n; i++)
 4     remain[i, i] = M - li;
 5       for (j = i + 1; j <= n; j++)
 6         remain[i, j] = remain[i, j-1] - lj - 1;
 7 }
 8 
 9 GET-CUBE()
10 {
11   for (i = 1; i <= n; i++)
12     for (j = i; j <= n; j++)
13     {
14       if (remain[i, j] < 0)
15         cube[i, j] = MAX;
16       else if (j==n && remain[i, j]>=0)
17         cube[i, j] = 0;
18       else
19         cube[i, j] = (remain[i, j])3;
20     }
21 }
22 
23 GET-SUM()
24 {
25   sum[0] = 0;
26   for (j = 1; j <= n; j++)
27   {
28     sum[j] = MAX;
29     for (i = 1; i <= j; i++)
30       if (sum[i-1] + cube[i, j] < sum[j])
31       {
32         sum[j] = sum[i-1] + cube[i, j];
33         p[j] = i;//用数组p来记录换行的位置
34       }
35   }
36 }
复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值