一个很显然的做法就是二分然后对于每个车贪心取check, 这肯定会TLE, 感觉会给人一种贪心去写的误导。。。
感觉有这个误导之后很难往dp那个方向靠。。
dp[ k ][ i ][ j ]表示把 i, j 这个区间分成 k 段, 所有段的最大值的最小值为多少。 然后dp的过程中把车代进去求答案。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 400 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; const double PI = acos(-1); int n, m; int a[N], f[2][N][N]; vector<pair<PII, int>> vc[N]; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= m; i++) { int s, f, c, r; scanf("%d%d%d%d", &s, &f, &c, &r); r = min(f - s + 1, r + 1); vc[r].push_back(mk(mk(s, f), c)); } LL ans = 0; int cur = 0, lst = 1; for(int i = 1; i <= n; i++) for(int j = i; j <= n; j++) f[cur][i][j] = a[j] - a[i]; for(int k = 2; k <= 401; k++) { swap(cur, lst); for(auto& t : vc[k - 1]) { ans = max(ans, 1ll * f[lst][t.fi.fi][t.fi.se] * t.se); } for(int i = 1; i <= n; i++) { int p = i + k - 2; for(int j = i + k - 1; j <= n; j++) { while(p < j && f[lst][i][p] <= a[j] - a[p]) p++; f[cur][i][j] = min(f[lst][i][p], a[j] - a[p - 1]); } } } printf("%lld ", ans); return 0; } /* */