zoukankan      html  css  js  c++  java
  • 【BZOJ】【3437】小P的牧场

    DP/斜率优化


      斜率优化基本题……等等,好像就没啥变化啊= =

      嗯目测这题跟仓库建设差不多?写题的时候倒是没想这么多……直接推了公式。

      $$f[i]=min{f[j]+cal(j,i)+a[i]}$$

      哦麻烦的还是这个$cal(j,i)$

      我们令$s[i]=sum_{k=1}^{i}b[k], c[i]=sum_{k=1}^{i}(b[k]*k)$

      则有$cal(j,i)=(s[i]-s[j])*i-(c[i]-c[j])$(问我怎么想到的?这个嘛……像这题这种要求“阶梯形求和”的,基本都是利用矩形和$sum_{k=1}^{i}a[k]*i=s[i]*i$ 以及 阶梯形和 $ sum (a[i]*i) $两种前缀和加加减减拼凑出来的)

      所以有$f[i]=min{ f[j]+(s[i]-s[j])*i-(c[i]-c[j])+a[i] }$

      单调性证明:$( j > k )$

    [ egin{aligned} f[j]+(s[i]-s[j])*i-(c[i]-c[j])+a[i] &< f[k]+(s[i]-s[k])*i-(c[i]-c[j])+a[i] \ f[j]-f[k]+c[j]-c[k] &< i*(s[j]-s[k]) \ frac{f[j]-f[k]+c[j]-c[k]}{s[j]-s[k]} &< i end{aligned} ]

     1 /**************************************************************
     2     Problem: 3437
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:2096 ms
     7     Memory:44240 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 3437
    11 #include<cmath>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cstdlib>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 #define pb push_back
    22 using namespace std;
    23 int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    27     return v*=sign;
    28 }
    29 const int N=1e6+10;
    30 typedef long long LL;
    31 /******************tamplate*********************/
    32 LL a[N],b[N],c[N],s[N],f[N];
    33 int q[N],l,r,n;
    34 inline double slop(int k,int j){
    35     return double(f[j]-f[k]+c[j]-c[k])/double(s[j]-s[k]);
    36 }
    37 int main(){
    38     n=getint();
    39     F(i,1,n) a[i]=getint();
    40     F(i,1,n){
    41         b[i]=getint();
    42         s[i]=s[i-1]+b[i];
    43         c[i]=c[i-1]+b[i]*i;
    44     }
    45     F(i,1,n){
    46         while(l<r && slop(q[l],q[l+1])<i)l++;
    47         int t=q[l];
    48         f[i]=f[t]+(s[i]-s[t])*i-c[i]+c[t]+a[i];
    49         while(l<r && slop(q[r-1],q[r])>slop(q[r],i))r--;
    50         q[++r]=i;
    51     }
    52     printf("%lld
    ",f[n]);
    53     return 0;
    54 }
    View Code

    3437: 小P的牧场

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 491  Solved: 272
    [Submit][Status][Discuss]

    Description


     背景

        小P是个特么喜欢玩MC的孩纸。。。

     描述

        小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧 场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边 不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控制站到牧场间修建道路是需要资源的嘛~),而且该花费等于它到控制 它的控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量,在第i个牧场建立控制站的花费是ai,每个牧场i的放养量是bi,理 所当然,小P需要总花费最小,但是小P的智商有点不够用了,所以这个最小总花费就由你来算出啦。

    Input

        第一行一个整数 n 表示牧场数目

        第二行包括n个整数,第i个整数表示ai

        第三行包括n个整数,第i个整数表示bi

     

    Output

       只有一行,包括一个整数,表示最小花费

    Sample Input

    4
    2424
    3142

    Sample Output


    9

    样例解释

    选取牧场1,3,4建立控制站,最小费用为2+(2+1*1)+4=9。

    数据范围与约定


    对于100%的数据,1<=n<=1000000,0

    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    Adobe Edge Animate –EdgeCommons Log和全局变量设置功能
    Adobe Edge Animate –使用EdgeCommons加载和播放音频
    Adobe Edge Animate –svg地图交互-精确的边缘及颜色置换
    Adobe Edge Animate –解决图形边缘精确检测问题-通过jquery加载svg图片
    Adobe Edge Animate –修改Edge Commons Spotlight功能,使之能支持播放中国网站视频
    Adobe Edge Animate –获取鼠标位置及跟随鼠标功能实现
    Adobe Edge Animate –使用css制作菜单
    Adobe Edge Animate –Edge Commons强势来袭,Edge团队开发成为现实
    Adobe Edge Animate –可重复使用的个性化按钮制作
    Adobe Edge Animate –弹性的方块-使用tweenmax缓动效果
  • 原文地址:https://www.cnblogs.com/Tunix/p/4333852.html
Copyright © 2011-2022 走看看