#include #include #include #include #include using namespace std; constexpr int MAXN = 5000; // Input data int n, w; vector words; vector ls; // maxl[l][r] for half open interval [l, r) array, MAXN + 1> maxl; // The index of the first larger value on the left/right. array L, R; // Test a given height bool test(int h) { vector dp(n + 1, 1e9); dp[0] = 0; for(int i = 1; i <= n; ++i) { auto low = max(i - h, 0); dp[i] = dp[low] + maxl[low][i] + 1; for(int j = i - 2; j >= low; j = L[j]) dp[i] = min(dp[i], dp[j + 1] + maxl[j + 1][i] + 1); } return dp[n] <= w + 1; } void print(int h) { vector dp(n + 1, 1e9); vector p(n + 1, -1); dp[0] = 0; for(int i = 1; i <= n; ++i) for(int j = max(0, i - h); j < i; ++j) if(auto x = dp[j] + maxl[j][i] + 1; x < dp[i]) { dp[i] = x; p[i] = j; } vector as{n}; for(int i = n; i;) as.push_back(i = p[i]); reverse(begin(as), end(as)); int c = as.size() - 1; vector ws(c); for(int i = 0; i < c; ++i) ws[i] = maxl[as[i]][as[i + 1]]; vector ans(h); for(int i = 0; i < c; ++i) for(int j = as[i], k = 0; k < h; ++j, ++k) ans[k] += j < as[i + 1] ? (words[j] + string(ws[i] + 1 - ls[j], ' ')) : string(ws[i] + 1, ' '); cout << h << " " << c << endl; for(auto x : ws) cout << x << ' '; cout << endl; for(auto x : ans) cout << x << endl; } int main() { cin >> n >> w; words.resize(n); ls.reserve(n); for(auto& w : words) cin >> w, ls.push_back(w.size()); // Fill maxl for(int l = 0; l < n; ++l) for(int r = l + 1, m = 0; r <= n; ++r) { m = max(m, ls[r - 1]); maxl[l][r] = m; } // Fill L and R for(int i = 0; i < n; ++i) { L[i] = i - 1; while(L[i] >= 0 and ls[i] > ls[L[i]]) L[i] = L[L[i]]; } for(int i = n - 1; i >= 0; --i) { R[i] = i + 1; while(R[i] < n and ls[i] > ls[R[i]]) R[i] = R[R[i]]; } int l = 1, h = n; while(l < h) { auto m = (l + h) / 2; if(test(m)) h = m; else l = m + 1; } print(l); }