BZOJ3156防御准备 斜率优化

Posted CQzhangyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3156防御准备 斜率优化相关的知识,希望对你有一定的参考价值。

【BZOJ3156】防御准备

Description

Input

第一行为一个整数N表示战线的总长度。

第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai。

Output

共一个整数,表示最小的战线花费值。

Sample Input

10
2 3 1 5 4 5 6 3 1 2

Sample Output

18

HINT

1<=N<=10^6,1<=Ai<=10^9

题解:一眼看出斜率优化DP,先列出方程再说

令f[i]表示在i处放置守卫塔,且i左面的格子都被保护时的最小花费。

$f[i]=min(f[j]+\\frac {(i-j)(i-j-1)} {2}+a[i]) (0\\le j < i)$

整理一下,发现求的是下凸包,且点的坐标单调不减

题目图片太大导致不能再加图片了好气~

#include <cstdio>
#include <iostream>
#include <cstring>
#define y(_) (f[_]+_*(_+1)/2)
using namespace std;
typedef long long ll;
const int maxn=1000010;
int n;
ll q[maxn],h,t;
ll a[maxn],f[maxn];
int main()
{
	scanf("%d",&n);
	ll i;
	for(i=1;i<=n;i++)	scanf("%lld",&a[i]);
	h=t=1;
	for(i=1;i<=n;i++)
	{
		while(h<t&&(y(q[h+1])-y(q[h]))<=i*(q[h+1]-q[h]))	h++;
		f[i]=f[q[h]]+(i-q[h])*(i-q[h]-1)/2+a[i];
		while(h<t&&(y(q[t])-y(q[t-1]))*(i-q[t])>=(y(i)-y(q[t]))*(q[t]-q[t-1]))	t--;
		q[++t]=i;
	}
	printf("%lld",f[n]);
	return 0;
}

以上是关于BZOJ3156防御准备 斜率优化的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3156 防御准备 动态规划 斜率优化

BZOJ 3156: 防御准备 斜率优化DP

[BZOJ3156]防御准备 斜率优化DP

3156: 防御准备(斜率优化)

BZOJ 3156 防御准备

bzoj3156 防御准备