• 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 }
  • 相关阅读:
    Android简易抽屉效果
    apk 下载并自动安装
    python2.7_1.3_获取远程设备的IP地址
    python2.7_1.2_打印设备名和IPv4地址
    python2.7_1.14_编写一个简单的回显客户端/服务器应用
    python2.7_1.13_编写一个SNTP客户端
    C语言程序转换为Python语言
    5分钟弄懂Docker!
    让正则表达式变简单(PythonVerbalExpressions)
    python sqlalchemy-migrate 使用方法
  • 原文地址:https://www.cnblogs.com/wsy01/p/8125938.html
Copyright © 2020-2023  润新知