Jzoj P6305 最小值___单调栈优化dp

题目大意:

在这里插入图片描述
在这里插入图片描述

分析:

d p i dp_i dpi表示分割了前i个,最大能得到的价值
初值: d p i = f ( m i n i = 1 i a i ) dp_{i}=f(min_{i=1}^{i}a_i) dpi=f(mini=1iai)
转移就是 d p i = d p j + f ( m i n i = j + 1 i a j ) dp_{i}=dp_{j}+f(min_{i=j+1}^{i}a_j) dpi=dpj+f(mini=j+1iaj)
然后用单调栈维护即可

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>

#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)

#define N 200005

using namespace std;

typedef long long ll;

ll cmin[N], dp[N], a[N], h[N], A, B, C, D, minnum = a[1];
int n, cnt;

ll Calc(ll x) {
	return A * x * x * x + B * x * x + C * x + D;
}

int main() {
	freopen("min.in", "r", stdin);
	freopen("min.out", "w", stdout);
	scanf("%d %lld %lld %lld %lld", &n, &A, &B, &C, &D);
	rep(i, 1, n) scanf("%lld", &a[i]);
	cmin[++cnt] = a[1]; h[cnt] = 0;
	rep(i, 1, n) {
		dp[i] = Calc(minnum);
		rep(j, 1, cnt) dp[i] = max(dp[i], h[j] + Calc(cmin[j])); 
	    if (i == n) break;
		ll hmax = dp[i];
		while (cnt >= 1 && cmin[cnt] >= a[i + 1]) hmax = max(hmax, h[cnt]), cnt--;
		cmin[++cnt] = a[i + 1], h[cnt] = hmax;
	    minnum = min(minnum, a[i + 1]);
	}
	printf("%lld\n", dp[n]);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值