AOJ2129 Text Justification
問題リンク Text Justification
- 概要
N個の単語長と幅Wが指定される。単語は入力の順に並べる。このとき、1行の文字幅がWに近付くように、改行を挿入できる。単語の途中に改行を入れることはできない。以下の方法にのっとって、単語の並べ方のコストを算出するとき、コストの最小値を求めよ。sは、1行に並べた単語長とする。
コストの値は、各行に関するコストの総和である
最終行のコストは、max{0, s-w}
それ以外の行のコストは、|s-w|
0 <= N <= 10^3
0 <= W <= 10^6
単語長 <= W
- 解法
DPです。
dp[i]: 単語iを行の最後としたときの最小コスト
という表を作ります。このとき、単語iは最終行でないものとして計算します。dp[i]は、累積和を使いつつ埋めればO(N^2)で埋まります。
最後に、最終行がiの単語から始まるとして、
min { dp[i-1] + max{0, sum[n]-sum[i-1]} }
が答えになります。
- ソース
import java.util.Scanner; //Text Justification public class AOJ2129 { void run(){ Scanner sc = new Scanner(System.in); int[] a = new int[1001], sum = new int[1001], dp = new int[1001]; int INF = (1<<30)-1; for(int T=1;;T++){ int n = sc.nextInt(), w = sc.nextInt(); if((n|w)==0)break; for(int i=1;i<=n;i++){ a[i] = sc.nextInt(); sum[i] = sum[i-1]+a[i]; dp[i] = INF; } for(int i=1;i<=n;i++)for(int j=0;j<i;j++)dp[i] = Math.min(dp[i], dp[j]+(Math.abs(sum[i]-sum[j]-w))); int res = INF; for(int i=1;i<=n;i++)res = Math.min(res, dp[i-1]+Math.max(0, sum[n]-sum[i-1]-w)); System.out.printf("Case %d: %d\n", T, res); } } public static void main(String[] args) { new AOJ2129().run(); } }