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

    BZOJ

    题意:(N(N<=10^6))个牧场,牧场i要么花费(a_i)放置控制站,要么花费它到它右边第一个控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量(b_i).求最小总花费.

    分析:防御准备仓库建设,这些题都差不太多.

    (f[i])表示在i点放置控制站的最小花费.

    (f[i]=min(f[j]+a[i]+(sum_{k=j+1}^{i-1}b[k]*(i-k))))

    (sum[i])表示(b[i])的前缀和,(s[i])表示(i*b[i])的前缀和,则上式可以写成

    (f[i]=f[j]+a[i]+i*(sum[i-1]-sum[j])-(s[i-1]-s[j]))

    (k<j)且j比k更优,即

    (f[j]+a[i]+i*(sum[i-1]-sum[j])-(s[i-1]-s[j])<f[k]+a[i]+i*(sum[i-1]-sum[k])-(s[i-1]-s[k]))

    整理上式得到,

    (frac{f[j]+s[j]-f[k]-s[k]}{sum[j]-sum[k]}<i)

    就可以斜率优化了.

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read(){
       int s=0,w=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
       return s*w;
    }
    const int N=1000005;
    int a[N],b[N],q[N];
    LL s[N],sum[N],f[N];
    inline double Count(int j,int k){return 1.0*(f[j]+s[j]-f[k]-s[k])/(double)(sum[j]-sum[k]);}
    int main(){
        int n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=n;i++){
    		b[i]=read();
    		sum[i]=sum[i-1]+b[i];
    		s[i]=s[i-1]+1ll*i*b[i];
        }
        int l=1,r=1;
        for(int i=1;i<=n;i++){
    		while(l<r&&Count(q[l+1],q[l])<=i)l++;
    		f[i]=f[q[l]]+a[i]+i*(sum[i-1]-sum[q[l]])-(s[i-1]-s[q[l]]);
    		while(l<r&&Count(q[r],q[r-1])>=Count(i,q[r]))r--;
    		q[++r]=i;
        }
        printf("%lld
    ",f[n]);
        return 0;
    }
    
    
  • 相关阅读:
    9.算术运算符
    7.字符串格式化
    下载和配置JDK
    Set-常用API及详解
    List-ApI及详解
    电路交换、报文交换、分组交换比较
    集合之List—ArrayList
    java的getClass()函数
    Object类、包装类、内部类详解
    接口的探究
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11016997.html
Copyright © 2011-2022 走看看