• 【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]) (0le 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;
    }
  • 相关阅读:
    多线程下单例模式:懒加载(延迟加载)和即时加载
    Java 线程同步
    java 多线程之wait(),notify,notifyAll(),yield()
    序列化和反序列化及线程实现方式
    错题解析
    错题解析
    考试:错题总结
    测试:错题总结
    hashCode与equals的区别与联系
    @Not
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6432965.html
Copyright © 2020-2023  润新知