【BZOJ】ZJOI2007仓库建设-斜率优化
2018-03-16 23:02
309 查看
传送门 BZOJ1096
的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,产品只能往山下运(即只能运往编号更大的工厂的仓库),运送产品需要费用的,假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据:1:工厂i距离工厂1的距离Xi(其中X1=0);2:工厂i目前已有成品数量Pi;:3:在工厂i建立仓库的费用Ci;请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。
先贴两篇博客:
斜率优化入门及例题
斜率优化Dp详解
学习斜率优化看上面这两篇博文就好啦~
然后讲讲这道题。我们如何构造一个一次函数的方程。
首先设f[i]为处理完第i个工厂的成品并且以第i个建立仓库。
可以得到如下状态转移方程:
f[i]=c[i]+min(f[j]+∑ik=j+1(x[i]−x[k])∗p[k]∑k=j+1i(x[i]−x[k])∗p[k]) (1<=j< i )
设s[t]=∑ti=1p[i]∑i=1tp[i],Q(t)=∑ti=1x[i]∗p[i]∑i=1tx[i]∗p[i],
化简上式得:
f[i]=c[i]+f[j]+x[i]*(s[i]-s[j])-Q(i)+Q(j) (我们暂时忽略取小操作)
然后就可以构造一次函数了!我们来移一下项。
f[i]-c[i]+x[i]*(s[j]-s[i])=f[j]+Q(j)-Q(i)
真是妙妙。我们现在可以把(f[i]-c[i])看做b(截距),x[i]看作k(斜率),(s[j]-s[i])看作x,(f[j]+Q(j)-Q(i))看作y。
剩下的操作就是斜率优化的一般步骤了。还不会的朋友可以看一看上面贴的两篇博文。
题意:
L公司有N个工厂,由高到底分布在一座山上。工厂1在山顶,工厂N在山脚。在某些工厂建立一些仓库。在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,产品只能往山下运(即只能运往编号更大的工厂的仓库),运送产品需要费用的,假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据:1:工厂i距离工厂1的距离Xi(其中X1=0);2:工厂i目前已有成品数量Pi;:3:在工厂i建立仓库的费用Ci;请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。
输入
第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。输出
仅包含一个整数,为可以找到最优方案的费用。数据范围
对于100%的数据, N ≤1000000。 所有的Xi, Pi, Ci均在32位带符号整数以内,保证中间计算结果不超过64位带符号整数。题解
今天本蒟蒻终于学会了斜率优化。先贴两篇博客:
斜率优化入门及例题
斜率优化Dp详解
学习斜率优化看上面这两篇博文就好啦~
然后讲讲这道题。我们如何构造一个一次函数的方程。
首先设f[i]为处理完第i个工厂的成品并且以第i个建立仓库。
可以得到如下状态转移方程:
f[i]=c[i]+min(f[j]+∑ik=j+1(x[i]−x[k])∗p[k]∑k=j+1i(x[i]−x[k])∗p[k]) (1<=j< i )
设s[t]=∑ti=1p[i]∑i=1tp[i],Q(t)=∑ti=1x[i]∗p[i]∑i=1tx[i]∗p[i],
化简上式得:
f[i]=c[i]+f[j]+x[i]*(s[i]-s[j])-Q(i)+Q(j) (我们暂时忽略取小操作)
然后就可以构造一次函数了!我们来移一下项。
f[i]-c[i]+x[i]*(s[j]-s[i])=f[j]+Q(j)-Q(i)
真是妙妙。我们现在可以把(f[i]-c[i])看做b(截距),x[i]看作k(斜率),(s[j]-s[i])看作x,(f[j]+Q(j)-Q(i))看作y。
剩下的操作就是斜率优化的一般步骤了。还不会的朋友可以看一看上面贴的两篇博文。
总结
总结一下,其实Dp的题,没有接触过很难想出来,但把每种Dp方法熟悉掌握之后,我们做题时只需要找到题目中最关键的状态转移方程,并用恰当的方法表示出来就好了。这样来看,如果不是新题,Dp的题目思维难度和代码难度其实都不高,但一定需要巧妙的思维,而且要能立刻反应过来时Dp。如斜率优化的题,打一两道就好了,其实流程都大同小异。代码
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> typedef long long ll; typedef double db; using namespace std; const int N=1e6+10; int n,p ,w ,q ,xi ;//p->Pi w->Ci q->双端队列 ll dis ,s ,dp ;//dis->Xi*Pi的前缀和,s->p的前缀和 inline ll x(int a){ return s[a]; } inline ll y(int a){ return dp[a]+dis[a]; } inline db rate(int a,int b){ return (db)(y(a)-y(b))/(db)(x(a)-x(b)); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d%d",&xi[i],&p[i],&w[i]); } for(int i=1;i<=n;i++){ s[i]=s[i-1]+(ll)p[i]; dis[i]=dis[i-1]+(ll)xi[i]*p[i]; } int head=1,tail=1; for(int i=1;i<=n;i++){ while(head<tail && rate(q[head],q[head+1])<xi[i]) head++; int now=q[head]; dp[i]=w[i]+dp[now]+xi[i]*(s[i]-s[now])-dis[i]+dis[now]; while(head<tail && rate(q[tail],q[tail-1])>rate(q[tail],i)) tail--; q[++tail]=i; } printf("%lld\n",dp ); return 0; }
相关文章推荐
- bzoj1096 [ZJOI2007]仓库建设(斜率优化)
- BZOJ_P1096 [ZJOI2007]仓库建设(斜率优化DP)
- 【BZOJ 1096】【ZJOI 2007】仓库建设 DP+斜率优化
- 【ZJOI2007】【BZOJ1096】仓库建设(斜率优化DP)
- BZOJ 1096 ZJOI2007 仓库建设 斜率优化
- bzoj 1096 [ZJOI2007]仓库建设(关于斜率优化问题的总结)
- [BZOJ1096][ZJOI2007]仓库建设(斜率优化dp)
- [斜率优化DP] BZOJ1096: [ZJOI2007]仓库建设
- BZOJ 1096 [ZJOI2007]仓库建设 斜率优化dp
- BZOJ 1096: [ZJOI2007]仓库建设【斜率优化】
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化DP
- BZOJ_1096_[ZJOI2007]_仓库建设_(斜率优化动态规划+单调队列+特殊的前缀和技巧)
- BZOJ 1096: [ZJOI2007]仓库建设 | 斜率优化DP
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp
- BZOJ 1096: [ZJOI2007]仓库建设(动态规划+斜率优化)
- _bzoj1096 [ZJOI2007]仓库建设【斜率优化dp】
- 【斜率优化DP】BZOJ1096 [ZJOI2007]仓库建设
- 【BZOJ】1096: [ZJOI2007]仓库建设(dp+斜率优化)
- bzoj1096 [ZJOI2007]仓库建设 斜率优化dp
- BZOJ1096(ZJOI2007)仓库建设--斜率优化DP