TCHS08 Online Round 3 Hard 練習
問題
正方形を無限にならべた横長の板があって、この上に高さが1で横の長さが決まっている長方形がいくつかある。この長方形を左右に動かして、ちょうど決められた範囲を覆うようにしたい。最低何回動かせばぴったり覆えるか求めなさい。
解
i個の長方形を使って、aから n + width - 1 までを覆うようにしたときの最小移動回数を dp[i, n] とする。
最終的にbまで覆うとき、一番右の長方形の左端は b - width + 1 になるので、ここまで繰り返す。
それであとは隙間ができないようにいてれーしょん。
using System; using System.Text; using System.Text.RegularExpressions; using System.Collections; using System.Collections.Generic; public class RectanglesArrangement { public int cover(int[] left, int width, int a, int b) { if (width > b - a + 1 || left.Length * width < b - a + 1) return -1; // 不可能なので帰ってもらう int[,] dp = new int[51, 1001]; for (int i = 0; i <= 50; i++) for (int j = 0; j <= 1000; j++) dp[i, j] = -1; Array.Sort(left); // 長方形をソートしておく dp[1, a] = Math.Abs(left[0] - a); // aに一番近い長方形をaにもっていく for (int i = 1; i < left.Length; ++i) { for (int j = a; j <= b - width + 1; ++j) // 長方形を置ける範囲 { if(dp[i, j] != -1) { for (int k = a; k <= b - width + 1; ++k) { if (k > j + width) continue; // 隙間を空けるなんて許さないんだからねっ if(dp[i + 1, Math.Max(j, k)] == -1) dp[i + 1, Math.Max(j, k)] = dp[i, j] + Math.Abs(left[i] - k); else dp[i + 1, Math.Max(j, k)] = Math.Min(dp[i + 1, Math.Max(j, k)], dp[i, j] + Math.Abs(left[i] - k)); } } } } return dp[left.Length, b - width + 1]; } }