• bzoj1096 [ZJOI2007]仓库建设


    这道题是比较裸的斜率优化吧,维护两个前缀和一减就可以得出斜率方程。

    然后就是模板类的题目了。

    转一下hzw的吧

    f[i]=min(f[j]+cal(j,i))

    主要问题是如何在O1的时间内计算cal(j,i),即j+1到i这一段存入i所需的费用

    我们可以利用前缀和的思想

    sum[i]为p[i]的前缀和

    如果所有物品都从0开始运到i,则费用为(sum[i]-sum[j])*x[i]

    但由于物品的起始点不在0,所以每个物品可以少花费x[i]*p[i]

    b[i]为x[i]*p[i]的前缀和

    可得f[i]=min(f[j]+(sum[i]-sum[j])*x[i]-(b[i]-b[j])+c[i]

    如果j>k且j比k更优

    f[j]-f[k]+b[j]-b[k]<(sum[j]-sum[k])*x[i]

    然后就解决了

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 const int NN=1e6+7;
    10 
    11 int n,l,r;
    12 ll x[NN],p[NN],c[NN],q[NN];
    13 ll f[NN],sum[NN],b[NN];
    14 double get_left(int j,int k)
    15 {
    16     return (f[j]-f[k]+b[j]-b[k])*1.0/(double)(sum[j]-sum[k]);
    17 }
    18 int main()
    19 {
    20     //freopen("1.in","r",stdin);
    21     //freopen("fzy.out","w",stdout);
    22     scanf("%d",&n);
    23     for (int i=1;i<=n;i++)
    24     {
    25         scanf("%d%d%d",&x[i],&p[i],&c[i]);
    26         sum[i]=sum[i-1]+p[i];
    27         b[i]=b[i-1]+p[i]*x[i];    
    28     }
    29     l=0;
    30     q[r++]=0;
    31     for (int i=1;i<=n;i++)
    32     {
    33         while(l+1<r&&(get_left(q[l+1],q[l])<=x[i])) l++;
    34         int best=q[l];
    35         f[i]=f[best]+(sum[i]-sum[best])*x[i]-(b[i]-b[best])+c[i];
    36         while(r-2>=l&&get_left(q[r-1],q[r-2])>get_left(i,q[r-1])) r--;
    37         q[r++]=i;    
    38     }
    39     printf("%lld",f[n]);
    40 }
  • 相关阅读:
    jQuery插件开发全解析(转)
    isMemberOfClass和isKindOfClass之间区别
    NSArray,NSSet,NSDictionary总结 (转)
    NSIndexPath(转)
    Maven在dos窗口中的命令
    JPA概要
    fedora的输入法
    iQQ 学习笔记2 :借助新浪微博输入验证码、远程控制退出
    使用EXCEL制作通用打印模块
    字符串加密解密方法
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7470800.html
Copyright © 2020-2023  润新知