思路:
对于 % 30 的数据,可以想到一个 Dp 方程:
其中dp[i]表示分割[1,i]的最大答案
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 const int Nt = 524287; const long long inf = 0x3f3f3f3f3f3f3f3f; 5 int ri() { 6 char c = getchar(); int x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1; 7 for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f; 8 } 9 int a[Nt], st[Nt], tp, n, A, B, C, D; 10 long long T[Nt << 1], f[Nt], mx[Nt]; 11 12 void Up(int i, long long x) 13 {for(T[i += Nt] = x; i >>= 1;) T[i] = std::max(T[i << 1], T[i << 1 | 1]);} 14 15 long long Cal(long long x) {return ((A * x + B) * x + C) * x + D;} 16 17 int main() { 18 freopen("min.in","r",stdin); 19 freopen("min.out","w",stdout); 20 n = ri(); A = ri(); B = ri(); C = ri(); D = ri(); 21 for(int i = 1;i <= n; ++i) a[i] = ri(); 22 std::memset(T, -0x3f, sizeof(T)); 23 f[0] = 0; mx[1] = 0; st[tp = 1] = a[1]; Up(1, Cal(a[1])); 24 for(int i = 1;i <= n; ++i) { 25 f[i] = T[1]; long long x = f[i]; 26 for(;st[tp] > a[i + 1] && tp;) x = std::max(x, mx[tp]), Up(tp--, -inf); 27 st[++tp] = a[i + 1]; mx[tp] = x; Up(tp, x + Cal(st[tp])); 28 } 29 printf("%lld ", f[n]); 30 return 0; 31 }