#include using namespace std; bool solve(int r, vector a, int W, bool do_print = false) { int n = a.size(); // dpL[i][w] = min { j | j >= i && len(a[j]) > w } vector> dpL(n+1, vector(W+1, n)); { for (int i = n-1; i >= 0; i--) { dpL[i] = dpL[i+1]; for (int w = 0; w < int(a[i].size()); w++) { dpL[i][w] = i; } } } // dp[w] = number of words that fit into width w vector dp(W+1), pred(W+1); for (int w = 1; w <= W; w++) { for (int v = 0; v < w; v++) { int cur = min(dp[v]+r, dpL[dp[v]][w-v-1]); if (cur > dp[w]) dp[w] = cur, pred[w] = v; } } if (dp[W] < n) return false; if (do_print) { while (W > 0 && dp[W-1] == n) W--; vector res(r, string(W-1,' ')); vector v = {W}; for (; W > 0; W = pred[W]) v.push_back(pred[W]); reverse(begin(v), end(v)); int c = int(v.size()) - 1; int k = 0, i = 0; for (string s: a) { if (i == r || int(s.size()) >= v[k+1]-v[k]) k++, i = 0; copy(begin(s), end(s), begin(res[i]) + v[k]), i++; } cout << r << " " << c << endl; for (int k = 0; k < c; k++) cout << v[k+1]-v[k]-1 << " \n"[k+1==c]; for (string s: res) cout << s << endl; } return true; } int main() { int n, W; cin >> n >> W; vector a(n); for (string &s: a) cin >> s; W++; int rmin = 0, rmax = n; while (rmax-rmin > 1) { int r = (rmin+rmax)/2; (solve(r, a, W) ? rmax : rmin) = r; } assert(solve(rmax, a, W, true)); }