二we线段树

本文介绍了如何使用斜率优化方法解决动态规划问题,通过实例《特别行动队》的DP求解过程,展示了如何通过状态转移方程和前缀和优化来简化计算。暴力代码和优化后的公式都进行了详细解释,适用于涉及平方项和特定变量的动态规划问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

特别行动队

题解:

显然遇到这种DP题我们要先打暴力,通过读题我们可以快速推出DP式子:

状态:设 d p [ i ] dp[i] dp[i]为前i个人的最大价值

状态转移方程:

( ∑ k = j + 1 i a [ k ] ) = X (\sum_{k = j + 1}^i a[k]) = X (k=j+1ia[k])=X

d p [ i ] = m a x ( d p [ j ] + a ∗ X 2 + b ∗ X + c ) dp[i] = max(dp[j] + a * X^2 + b * X + c) dp[i]=max(dp[j]+aX2+bX+c)

累加我们可以直接前缀和优化,设 ( ∑ k = 1 i a [ k ] ) = S u m i (\sum_{k=1}^i a[k]) = Sum_i (k=1ia[k])=Sumi

那么转移方程即可化为: d p [ i ] = m a x ( d p [ j ] + a ∗ ( S u m i − s u m j ) 2 + b ∗ ( S u m i − s u m j ) + c ) dp[i] = max(dp[j] + a * (Sum_i - sum_j)^2 + b *(Sum_i - sum_j) + c) dp[i]=max(dp[j]+aSumisumj)2+bSumisumj)+c)

至此如果你不像作者一样SB把初始化搞错,那么你已经有50分的高分

暴力代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1000005;
long long n, a, b, c, x[MAXN], sum[MAXN], dp[MAXN];
int main() {
    scanf("%lld %lld %lld %lld", &n, &a, &b, &c);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &x[i]);
        sum[i] = sum[i - 1] + x[i];
        dp[i] = -0x7f7f7f7f7f7f7f;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < i; j++) {
            int X = (sum[i] - sum[j]);
            dp[i] = max(dp[i], dp[j] + a * X * X + b * X + c);
        }
    }
    printf("%lld", dp[n]);
}

通过观察式子,发现带有平方以及二次项,并且不定的只有个j,再根据标签我们断定这道题要用斜率优化

那么我们开始推式子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值