zoukankan      html  css  js  c++  java
  • bzoj3156防御准备 斜率优化dp

    3156: 防御准备

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 2279  Solved: 959
    [Submit][Status][Discuss]

    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

    Source

    Katharon+#1

    f[i]=f[j]+(i-j)*i-(sum[i]-sum[j])+a[i]
    递推方程式和1096有点类似
    sum[i]表示i到1的距离

    设k<j && j 优于 k
    f[j]+(i-j)*i-(sum[i]-sum[j])+a[i]<=f[k]+(i-k)*i-(sum[i]-sum[k])+a[i]
    化简得f[j]-i*j+sum[j]<=f[k]-i*k+sum[k]

    证明决策单调性
    需要证明 对于 t>i j的决策优于k
    即f[j]-t*j+sum[j]<=f[k]-t*k+sum[k]
    设t=i+v 代入上式得
    f[j]-i*j+sum[j]-v*j<=f[k]-i*k+sum[k]-v*k
    -v*j<=-v*k 上式成立 决策单调性得证
    证毕

    斜率方程式
    假设k<j&&j决策优与k
    满足f[j]-i*j+sum[j]<=f[k]-i*k+sum[k]
    => f[j]+sum[j]-f[k]-sum[k]<=i*(j-k)
    => (f[j]+sum[j]-f[k]-sum[k])/(j-k)<=i
    优化dp即可

     1 #include<bits/stdc++.h>
     2 #define N 1000005
     3 #define ll long long
     4 using namespace std;
     5 ll sum[N],f[N];
     6 int n,q[N],a[N];
     7 inline char gc(){
     8     static char s[1000000],*p1,*p2;
     9     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
    10     if(p1==p2)return EOF;return *p1++;
    11 }
    12 inline int read(){
    13     int x=0;char ch=gc();
    14     while(ch<'0'||ch>'9')ch=gc();
    15     while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=gc();
    16     return x;
    17 }
    18 ll U(int k,int j){return f[j]+sum[j]-f[k]-sum[k];}
    19 int D(int k,int j){return j-k;}
    20 int main(){
    21     n=read();
    22     for(register int i=1;i<=n;++i){
    23         a[i]=read();
    24         sum[i]=sum[i-1]+i;
    25     }
    26     int h=1,t=1,j;
    27     for(register int i=1;i<=n;++i){
    28         while(h<t&&D(q[h],q[h+1])*i>=U(q[h],q[h+1]))++h;
    29         j=q[h];f[i]=f[j]+1ll*(i-j)*i-sum[i]+sum[j]+a[i];
    30         while(h<t&&U(q[t],q[t-1])*D(i,q[t])>=U(i,q[t])*D(q[t],q[t-1]))--t;
    31         q[++t]=i;
    32     }
    33     printf("%lld
    ",f[n]);
    34     return 0;
    35 }
  • 相关阅读:
    R语言画图教程之盒形图
    赵雅智_SimpleCursorAdapter
    java File文件操作共用方法整理
    Swift开发教程--怎样播放图片动画
    N!
    逻辑斯蒂有限增长模型
    Android app身体质量指数(BMI)
    Golang-interface(二 接口与nil)
    putty software caused connection abort
    卖了5个月水果之后再看互联网思维
  • 原文地址:https://www.cnblogs.com/wsy01/p/8125938.html
Copyright © 2011-2022 走看看