zoukankan      html  css  js  c++  java
  • BZOJ3437: 小P的牧场

    【传送门:BZOJ3437


    简要题意:

      一条线上有n个点,每个点都有一个权值,每个点都可以选择放置一个监测器,假设i点有监测器,那么假设i点左边最靠近i点的监测器在j点,那么i点的监测器就可以监测j+1到i的所有点

      每个点放置监测器都有花费(这个花费不是点的权值),而且假设在y点放置了监测器,并且y点的监测器监测了x到y的所有点,那么除了放置监测器的花费之外,还需要将x到y-1里的点消耗额外的花费:设k点在x到y-1的点中,那么k点会消耗y点与k点之间的点数(不算k点,但是算y点)乘上k的权值

      要求能监测到n个点(也意味着第n个点必须要放监测器)的最小费用


    题解:

      DP,数据范围太大只能DP

      f[i]表示在第i个位置放置监测器的最小费用,显然直接DP会T

      那么就斜率优化

      f[i]=min(f[j]+a[i]+(i-(j+1))*b[j+1]+(i-(j+2))*b[j+2]...)

      其实可以发现

      f[i]=min(f[j]+a[i]+i*b[j+1]-(j+1)*b[j+1]+i*b[j+2]-(j+2)*b[j+2]...)

      f[i]=min(f[j]+a[i]+i*(b[j+1]+b[j+2]+...)-(j+1)*b[j+1]-(j+2)*b[j+2]...)

      设sb[i]=b[1]+b[2]+...+b[i]

      cb[i]=b[1]*1+b[2]*2+b[3]*3...+b[i]*i

      然后就得到f[i]=min(f[j]+a[i]+i*(sb[i-1]-sb[j])-(cb[i-1]-cb[j]))

      接着化简斜率方程,设j1<j2<i

      (f[j2]-f[j1]+cb[j2]-cb[j1])/(sb[j2]-sb[j1])<i的时候,淘汰j1

      然后A了,要加long long


    参考代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    LL f[1100000];
    LL a[1100000],b[1100000];
    LL sb[1100000],cb[1100000];
    //f[i]=min(f[j]+a[i]+i*(sb[i-1]-sb[j])-(cb[i-1]-cb[j]))
    double slop(int j1,int j2)//(f[j2]-f[j1]+cb[j2]-cb[j1])/(sb[j2]-sb[j1])<i
    {
        return (f[j2]-f[j1]+cb[j2]-cb[j1])/(sb[j2]-sb[j1]);
    }
    int list[1100000];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        sb[0]=0;cb[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&b[i]);
            sb[i]=sb[i-1]+b[i];
            b[i]*=i;
            cb[i]=cb[i-1]+b[i];
        }
        int head=1,tail=1;list[1]=0;
        for(int i=1;i<=n;i++)
        {
            while(head<tail&&slop(list[head],list[head+1])<double(i)) head++;
            int j=list[head];
            f[i]=f[j]+a[i]+i*(sb[i-1]-sb[j])-(cb[i-1]-cb[j]);
            while(head<tail&&slop(list[tail-1],list[tail])>slop(list[tail],i)) tail--;
            list[++tail]=i;
        }
        printf("%lld
    ",f[n]);
        return 0;
    }

     

  • 相关阅读:
    pop指令的执行过程
    ipad 4.2 开发环境
    XP远程桌面
    停机问题、哥德尔定理
    看MIT的线性代数
    VizA项目继续推进
    port systemc to mac os x
    关于jar
    普桑
    拉突爾
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7884587.html
Copyright © 2011-2022 走看看