- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态规划之队列优化
动态规划之队列优化
浙江省镇海中学 贺洪鸣
【例1锯木场选址】(CEOI2004)
从山顶上到山底下沿着一条直线种植了n棵树。当地的政府决定把他们砍下来。为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂。木材只能按照一个方向运输:朝山下运。山脚下有一个锯木厂。另外两个锯木厂将新修建在山路上。你必须决定在哪里修建两个锯木厂,使得传输的费用总和最小。假定运输每公斤木材每米需要一分钱。
任务
你的任务是写一个程序:
从标准输入读入树的个数和他们的重量与位置
计算最小运输费用
将计算结果输出到标准输出
输入
输入的第一行为一个正整数n——树的个数(2≤n≤20 000)。树从山顶到山脚按照1,2……n标号。接下来n行,每行有两个正整数(用空格分开)。第i+1行含有:vi——第i棵树的重量(公斤为单位)和 di——第i棵树和第i+1棵树之间的距离,1≤vi ≤10 000,0≤di≤10 000。最后一个数dn,表示第n棵树到山脚的锯木厂的距离。保证所有树运到山脚的锯木厂所需要的费用小于2000 000 000分。
输出
输出只有一行一个数:最小的运输费用。
样例输入
样例输出269
样例输出
26
1 2
2 1
3 3
1 1
3 2
1 6
2 1
1 2
1 1
在解决这一问题时,首先我们要明确,将锯木厂建立在相邻两棵树之间是没有任何意义的,否则我们可以将这样的锯木厂上移到最近的一棵树处,此时运送上方树木的费用减少,运送下方树木的费用没有变化,总费用降低。
为了方便讨论,我们先作如下定义:
假设山脚锯木场处也有一棵树,编号为,并且v[n+1]=d[n+1]=0。
表示第1棵树到第棵树的质量和,即。
表示第1棵树到第棵树的距离,即。特别的,有,表示第1棵树到自己的距离为0。
c[i]表示在第棵树处建一个锯木厂,并且将第1到第i棵树全部运往这个伐木场所需的费用。显然有c[i]=c[i-1]+sumw[i-1]*d[i-1]。特别的,有c[1]=0。
w[j,i]表示在第棵树处建一个锯木场,并且将第j到第i棵树全部运往这个锯木场所需的费用。则w[j,i]=c[i]-c[j-1]-sumw[j-1]*(sumd[i]-sumd[j-1])。特别的,当i=j时w[j,i]=0。
综上可知,求出所有sumw[i],sumd[i]与c[i]的时间复杂度为O(n),此后求任意w[j,i]的时间复杂度都为O(1)。
设f[i]表示在第i棵树处建立第二个锯木场的最小费用,则有。直接用这个式子计算的时间复杂度为,由于问题规模太大,直接使用这一算法必然超时,因此我们必须对算法进行优化。在讨论如何进行优化以前,我们首先证明下面这一猜想。
[猜想]
如果在位置i建设第二个锯木厂,第一个锯木厂的位置是j时最优。那么如果在位置i+1建设第二个锯木厂,第一个锯木厂的最佳位置不会小于j。
证明:假设第1个锯木厂建立在第j个处时,f[i]取得最优值,且此时j为f[i]取得最优值时的最小值,如下图所示.此时f[i]=c[j]+w[j+1,i]+w[i+1,n+1]
则对于任意的kj,
c[k]+w[k+1,i]+w[i+1,n+1]c[j]+w[j+1,i]+w[i+1,n+1]
c[k]+w[k+1,i]c[j]+w[j+1,i]
c[k]+w[k+1,i]c[j]+w[j+1,i]
第i至第i+1的距离第k+1至第i的总重量
第i至第i+1的距离
第k+1至第i的总重量
c[k]+w[k+1,i]+(sumw[i]-sumw[k])*d[i]c[j]+w[j+1,i]+(sumw[i]-sumw[k])*d[i]
c[k]+w[k+1,i]+(sumw[i]-sumw[k])*d[i]c[j]+w[j+1,i]+(sumw[i]-sumw[k])*d[i]
第j+1至第i的总重量,必小于第k+1至第i的总重量
第j+1至第i的总重量,
必小于第k+1至第i的总重量
c[k]+w[k+1,i]+(sumw[i]-sumw[k])*d[i]c[j]+w[j+1,i]+(sumw[i]-sumw[j])*d[i]
c[k]+w[k+1,i]+(sumw[i]-sumw[k])*d[i]c[j]+w[j+1,i]+(sumw[i]-sumw[j])*d[i]
c[k]+w[k+1,i+1]c[j]+w[j+1,i+1]
c[k]+w[k+1,i+1]c[j]+w[j+1,i+1]
c[k]+w[k+1,i+1]+w[i+2,n+1]c[j]+w[j+1,i+1]+w[i+2,n+1]
c[k]+w[k+1,i+1]+w[i+2,n+1]c[j]+w[j+1,i+1]+w[i+2,n+1]
即求f[i+1]时,决策k比决策j来得差!因此,当f[i]的第一个最佳决策
文档评论(0)