[题解]P3628 [APIO2010] 特别行动队

思路

我们定义 dpi 为选取前 i 个人所得到的最大的价值。

那么,我们能得出一个很简单的状态转移方程:

dpi=max(dpj+a×(k=j+1ixi)2+b×(k=j+1ixi)+c)

用前缀和优化,得:

dpi=max(dpj+a×(sxisxj)2+b×(sxisxj)+c)

然后,拆开括号,得:

dpi=max(dpj+a×sxi22a×sxi×sxj+a×sxj2+b×sxib×sxj+c)

如果当前选 j2 优于 j1,那么,当且仅当满足如下条件:

dpj1+a×sxi22a×sxi×sxj1+a×sxj12+b×sxib×sxj1+c<dpj2+a×sxi22a×sxi×sxj2+a×sxj22+b×sxib×sxj2+c

化简得:

2a×sxi<(dpj2+a×dpj22b×sxj2)(dpj1+a×dpj12b×sxj1)sxj2sxj2

令:

  1. 2a×sxiK
  2. sxxX(x)
  3. dpx+a×sxx2b×sxxY(x)

那么,得:

K<Y(j2)Y(j1)X(j2)X(j1)

那么,要使答案尽可能的大,最有抉择点必定在上凸包上,用斜率优化 DP 维护即可。

Code

#include <bits/stdc++.h>  
#define int long long  
#define re register  
  
using namespace std;  
  
const int N = 1e6 + 10;  
int n,a,b,c,hh = 1,tt = 1;  
int arr[N],dp[N],q[N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline int K(int i){  
    return 2 * a * arr[i];  
}  
  
inline int X(int i){  
    return arr[i];  
}  
  
inline int Y(int i){  
    return dp[i] + a * arr[i] * arr[i] - b * arr[i];  
}  
  
inline double sl(int i,int j){  
    return 1.0 * (Y(i) - Y(j)) / (X(i) - X(j));  
}  
  
signed main(){  
    n = read();  
    a = read();  
    b = read();  
    c = read();  
    for (re int i = 1;i <= n;i++) arr[i] = arr[i - 1] + read();  
    for (re int i = 1;i <= n;i++){  
        while (hh < tt && K(i) <= sl(q[hh],q[hh + 1])) hh++;  
        int j = q[hh];  
        dp[i] = dp[j] + a * (arr[i] - arr[j]) * (arr[i] - arr[j]) + b * (arr[i] - arr[j]) + c;  
        while (hh < tt && sl(q[tt],q[tt - 1]) <= sl(i,q[tt - 1])) tt--;  
        q[++tt] = i;  
    }  
    printf("%lld",dp[n]);  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18268796

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示