版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/88699682
【题目链接】
【思路要点】
- 枚举行宽, 计算最长河流长度即可。
- 具体来说,可以作为一个空位的前驱的空位至多有 个,且是单调的,因此使用 来进行一个简单 即可。
- 时间复杂度 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2505; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } char s[MAXN]; int n, a[MAXN], layer[MAXN], endp[MAXN], dp[MAXN]; int main() { read(n); int Llen = 0, Rlen = -1; for (int i = 1; i <= n; i++) { scanf("%s", s + 1); a[i] = strlen(s + 1); chkmax(Llen, a[i]); Rlen += a[i] + 1; } int ans = 0, Max = 0; for (int len = Llen; len <= Rlen; len++) { for (int i = 1; i <= n; i++) { if (i == 1 || endp[i - 1] + 1 + a[i] > len) layer[i] = layer[i - 1] + 1, endp[i] = a[i]; else layer[i] = layer[i - 1], endp[i] = endp[i - 1] + a[i] + 1; } int res = 0, pos = 1; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { while (pos < i && (layer[pos] < layer[i] - 1 || layer[pos] == layer[i] - 1 && endp[pos] < endp[i] - 1)) pos++; if (layer[pos] == layer[i] - 1 && endp[pos] <= endp[i] + 1) chkmax(dp[i], dp[pos]); if (pos + 1 <= i && layer[pos + 1] == layer[i] - 1 && endp[pos + 1] <= endp[i] + 1) chkmax(dp[i], dp[pos + 1]); if (layer[i] != layer[i + 1]) dp[i] = 0; else dp[i]++; chkmax(res, dp[i]); } if (res > Max) ans = len, Max = res; } printf("%d %d\n", ans, Max); return 0; }