题目链接
设有 N 堆石子排成一排,其编号为 1,2,3,…,N。
每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N 堆石子合并成为一堆。
每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。
例如有 4 堆石子分别为 1 3 5 2
, 我们可以先合并 1、2 堆,代价为 4,得到 4 5 2
, 又合并 1,2 堆,代价为 9,得到 9 2
,再合并得到 11,总代价为 4+9+11=24;
如果第二步是先合并 2,3 堆,则代价为 7,得到 4 7
,最后一次合并代价为 11,总代价为 4+7+11=22。
问题是:找出一种合理的方法,使总的代价最小,输出最小代价。
输入格式
第一行一个数 N 表示石子的堆数 N。
第二行 N 个数,表示每堆石子的质量(均不超过 1000)。
输出格式
输出一个整数,表示最小代价。
数据范围
1≤N≤5000
输入样例:
输出样例:
解题思路
四边形不等式优化dp
本题是二维四边形不等式的优化dp模板题
f[i][j]=mini≤k<j{f[i][k]+f[k+1][j]+w[i][j]},其中 f[i][i]=w[i][i]=0,如果 w 满足四边形不等式,且对于任意的 a≤b≤c≤d,都有 w(a,d)≥w(b,c),则 f 也满足四边形不等式
证明:
这里应用数学归纳法证明:
- 首先先证明 j−i=1 的情况,对于 i<i+1=j<j+1,即要证明 f[i][j+1]+f[i+1][j]≥f[i][j]+f[i+1][j+1],而 f[i][j+1]+f[i+1][j]=f[i][i+2]+f[i+1][i+1]=f[i][i+2],这时枚举 f[i][i+2] 的最优决策,假设其最优决策为 i,则有 f[i][i+2]=f[i][i]+f[i+1][i+2]+w(i,i+2)=w(i+1,i+2)+w(i,i+2)≥w(i+1,i+2)+w(i,i+1)=f[i+1][i+2]+f[i][i+1]=f[i+1][j+1]+f[i][j],满足要求;其最优决策为 i+1 时同理可得
- 当 j−i<k 时,f 满足四边形不等式,要证 j−i=k 时 f 也满足四边形不等式
假设 x,y 分别为 f[i][j+1],f[i+1][j] 的最优决策,设 i≤x≤y,则有:
对于 f[i][j+1]+f[i+1][j] 有:
f[i][j+1]+f[i+1][j]=f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j)
对于 f[i][j]+f[i+1][j+1] 有:
f[i][j]+f[i+1][j+1]≤f[i][x]+f[x][i]+w(i,j)+f[i+1][y]+f[y+1][j+1]+w(i+1,j+1)
又因为 w 满足四边形不等式,即 w(i,j+1)+w(i+1,j)≥w(i,j)+w(i+1,j+1)
又因为 x+1≤y+1≤j<j+1,这里面先验证是否有 j−(x+1)<k,因为 j−i=k,i≤x,即 j−k≤x,即 j−(x+1)<k,故这种状态满足四边形不等式,得:f[x+1][j+1]+f[y+1][j]≥f[x+1][j]+f[y+1][j+1],则比较 f[i][j+1]+f[i+1][j] 和 f[i][j]+f[i+1][j+1] 转化后的式子,可得 f[i][j+1]+f[i+1][j]≥f[i][j]+f[i+1][j+1],其他情况同理
二维决策单调性:设 p[i][j] 为 f[i][j] 的最优决策,如果 f 满足四边形不等式,则对于任意的 i<j,都有 p[i][j−1]≤p[i][j]≤p[i+1][j]
证明:
设 p=p[i][j],对于任意的 i<i+1≤k≤p,由 f 的四边形不等式,得 f[i][p]+f[i+1][k]≥f[i][k]+f[i+1][p],即有 f[i+1][k]−f[i+1][p]≥f[i][k]−f[i][p],又因为 p 是 f[i][j] 的最优决策,则有 f[i][k]+f[k+1][j]≥f[i][p]+f[p+1][j],则有 f[i+1][k]+f[k+1][j]+w(i+1,j)−(f[i+1][p]+f[p+1][j]+w(i,j+1))=(f[i+1][k]−f(f[i+1][p])+(f[k+1][j]−f[p+1][j])≥(f[i][k]−f[i][p])+(f[k+1][j]−f[p+1][j])=(f[i][k]+f[k+1][j])−(f[i][p]+f[p+1][j])≥0,即对于 f[i+1][j] 来说,p 比 k≤p 更优,则有 p[i][j]≤p[i+1][j],同理可证 p[i][j−1]≤p[i][j]
复杂度分析:复杂度为 O(∑n−1l=1∑nr=l+1(p[l+1][r]−p[l][r−1]+1)),不难发现,除非 l=1 或 r=n,其他都会消去,所以最后最多剩下 O(n),效果,且每一项都是 O(n) 规模,则:
代码
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2021-12-10 2983. 玩具