题目描述

题解
来自 https://photo.codefine.site:12524/wp-content/uploads/2021/03/introduction_to_algorithms_third_edition_en.pdf
输入
7 10
word like first as the the complete
输出
36
java 版解答
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class PrintNeatly {
public static void main(String[] args) throws IOException {
solve2();
}
static void solve1() throws IOException {
StreamTokenizer streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));
while(streamTokenizer.nextToken() != StreamTokenizer.TT_EOF){
int n = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
int M = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
String[] strings = new String[n + 1];
int[] l = new int[n + 1];
int[] p = new int[n + 1];
int[] c = new int[n + 2];
int[][] extra = new int[n + 1][n + 1];
int[][] lc = new int[n + 1][n + 1];
int rowMaxWord = (int)Math.floor(M * 1.0/ 2);
for (int i = 1; i <= n; ++i){
strings[i] = streamTokenizer.sval;
l[i] = strings[i].length();
if (i < n){
streamTokenizer.nextToken();
}
}
for (int i = 1; i <= n; ++i){
extra[i][i] = M - l[i];
for (int j = i + 1; j <= n; ++j){
if (j - i + 1 <= rowMaxWord){
extra[i][j] = extra[i][j - 1] - l[j] - 1;
}
}
}
for (int i = 1; i <= n; ++i){
for (int j = i; j <= n; ++j){
if (j - i + 1 > rowMaxWord || extra[i][j] < 0){
lc[i][j] = Integer.MAX_VALUE - 10000;
}else if (j == n && extra[i][j] >= 0){
lc[i][j] = 0;
}else {
lc[i][j] = extra[i][j] * extra[i][j] * extra[i][j];
}
}
}
c[0] = 0;
for (int j = 1; j <= n; ++j){
c[j] = Integer.MAX_VALUE;
for (int i = Math.max(1, j - rowMaxWord + 1); i <= j; ++i){
if (c[i - 1] + lc[i][j] < c[j]){
c[j] = c[i - 1] + lc[i][j];
p[j] = i;
}
}
}
System.out.println(c[n]);
print(strings, p, n);
}
}
static void solve2() throws IOException {
StreamTokenizer streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));
while(streamTokenizer.nextToken() != StreamTokenizer.TT_EOF){
int n = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
int M = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
String[] strings = new String[n + 1];
int[] l = new int[n + 1];
int[] p = new int[n + 1];
int[] c = new int[n + 1];
int rowMaxWord = (int)Math.floor(M * 1.0/ 2);
for (int i = 1; i <= n; ++i){
strings[i] = streamTokenizer.sval;
l[i] = strings[i].length();
if (i < n){
streamTokenizer.nextToken();
}
}
c[0] = 0;
int[] lcc = new int[n + 1];
for (int j = 1; j <= n; ++j){
c[j] = Integer.MAX_VALUE;
for (int i = j; i >= Math.max(1, j - rowMaxWord + 1); --i){
if (i == j){
lcc[i] = M - l[j];
}else{
lcc[i] = lcc[i + 1] - l[i] - 1;
}
}
for (int i = Math.max(1, j - rowMaxWord + 1); i <= j; ++i){
if (lcc[i] < 0){
lcc[i] = Integer.MAX_VALUE - 100000;
}else if (j == n){
lcc[i] = 0;
}else{
lcc[i] = lcc[i] * lcc[i] * lcc[i];
}
int cost = c[i - 1] + lcc[i];
if (cost < c[j]){
c[j] = cost;
p[j] = i;
}
}
}
writer.println(c[n]);
print(strings, p, n);
}
}
static int print(String[] s,int[] p, int j){
int i = p[j];
int row;
if (i == 1){
row = 1;
}else{
row = print(s, p ,i - 1) + 1;
}
for (int t = i; t <= j; ++t){
System.out.print(s[t]);
System.out.print(t == j ? "\n" : " ");
}
return row;
}
}