bzoj1096

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

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

转一下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 }
时间: 2024-10-26 17:31:15

bzoj1096的相关文章

【bzoj1096】仓库建设——斜率优化dp

题目链接 我们用sum[i]表示前i个工厂的产品数之和,b[i]表示x[i]*p[i]的前缀和,因此第j+1~i个工厂的产品运到第i个工厂的代价就是 (sum[i]-sum[j])*x[i]-(b[i]-b[j])+ci[i] 最后f[i]的状态转移方程即为: f[i]=f[j]+(sum[i]-sum[j])*xi[i]-(b[i]-b[j])+ci[i] 斜率式的推导过程就不写了,最后可以化成: (f[j]+b[j]-f[k]-b[k])/(sum[j]-sum[k])<xi[i]-ci[i

bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对

【BZOJ-1096】仓库建设 斜率优化DP

1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3719  Solved: 1633[Submit][Status][Discuss] Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先

bzoj1096【ZJOI2007】仓库建设

1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3659  Solved: 1602 [Submit][Status][Discuss] Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内 陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象 部门的电话,被告知三天之后将有一场暴雨,

[BZOJ1096] [ZJOI2007] 仓库建设 (斜率优化dp)

Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏

bzoj1096:dp+斜率优化

感觉斜率优化还是比较容易的,只是推的过程也不是很难,转换成代码的时候太久没打有点慢,加油! ------------------------------------------------------------------------------------------------------ #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namesp

【状态表示】Bzoj1096 [SCOI2008] 着色方案

Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案. Input 第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck. Output 输出一个整数,即方案总数模1,000,000,007的结果. Sample Input 3 1 2 3 Sample Out

BZOJ1096 [ZJOI2007]仓库建设

蒟蒻就写一下简单题吧... 此题很容易写出dp的方程: 令f[i]表示i号点要建仓库的话最小总费用,则 f[i] = min(f[j]  + (x[i] - x[j + 1]) * p[i + 1] + (x[i] - x[j + 2])* p[i + 2] + ... + (x[i] - x[i]) * p[i]) + c[i] 然后把min里面的东西展开再合并,并且令 sp[i] = p[1] + p[2] + ... + p[i] s[i] = x[1] * p[1] + x[2] * p

[Bzoj1096][ZJOI2007]仓库建设(斜率优化)

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1096 一开始想了想费用流,然后被数据范围pass掉了,感觉dp更可行一些. 只想到一个O(n2)的做法,看到式子比较复杂,就感觉像是斜率优化. dp[i]表示前i个工厂所求的最小费用,则第i个工厂一定会建一个仓库.转移方程为$dp[i]=min(dp[j]+\sum_{k=j}^{i-1}p[k]*(x[i]-x[k]))+c[i]$. 将式子展开,用sump表示p数组的前缀和,sum