The Great Wall II[dp/单调栈优化]

题目描述

Beacon towers are built throughout and alongside the Great Wall. There was once a time when there were n beacon towers built from west to east for defending against the invaders. The altitude of the i-th beacon tower, based on historical records, is ai​.

The defenders divide strategically all beacon towers into k parts where each part contains several, but at least one, consecutive beacon towers. To fully defend against the invaders, to each part a team of defenders should be assigned, the cost of which is given by the highest altitudes of beacon towers in that part.

As a historian, you are dying to know the minimum costs of assignments for every k=1,2,…,n

题意

现在有n(1<=n<=8000)个数,求分成k段的最小代价,每一段的代价等于这一段数组的最大值

分析

先考虑一种O(n^3)的做法,这种做法非常自然(并不)  ,我们考虑将前i个数字分成j段的最小代价,于是自然有转移方程

dp[i][j]=min_{0<=p<i}(dp[p][j-1]+max_(p<t<=i)(a[t]))

这种做法没有任何问题,除了时间复杂度有亿点点大。

接着我们考虑将其优化,这里我稍微走了一点弯路,如果不想看建议挑过下一段。

首先,考虑到后面有一个区间的最大值,我的反应是预处理一下,求出这段最大值后,我们就可以快速得出这一段的最值,这样才是真正的N^3做法,要是没有预处理的话,可能还得到N^4,不过这种简单操作应该没什么人不会吧  。这样上式就可以写成dp[i][j]=min_{0<=p<i}(dp[p][j-1]+maxx[p+1][i]),然后对于每一个j来说,dp【p】【j】都是可以提前计算出来的,而对于i,i增大时,后面那个值是不递减的,只会变得更大或者不变,而对于决策p来说,后面的值是不递增的,这样我们就可以大大缩小我们的决策范围,如果dp【p】【j-1】比前一个小,那么势必比前一个决策更优,反之比它大,由于maxx的对p不递增性,是无法保证哪一个更优的,而每一个i+1实际上只是比i多了dp【i】【j-1】项,因此我们就可以据此优化我们的dp。但是这种优化非常的玄学,你会发现在最劣情况下,仍然是N^3的复杂度,但跑出来的结果会比N^3好很多

上面是我走的弯路,虽然饶了点路,但还是对之后的思考很有帮助(并不)  ,那么接下来就是正题。在上面的优化中,我们发现之所以无法保证N^2,是因为后面的maxx的值的影响,如果是严格递减或者完全不变,情况会好很多,但是我们并不知道究竟怎样才会发生变化。重新回顾我们的决策,我们可以将其分为两类,一类是a【i】作为最后一段的最大值,一类是a【i】不作为最后一段的最大值,对于后者,我们发现dp【i】【j】的值似乎是由上一个比i大的数决定的,设这个位置是pre【i】,那么不管怎么分最后一段的贡献就是a【pre【i】】 ,    那么答案就是                          dp【pre【i】】【j】。

然后考虑a【i】作为最后一段的最大值,那么断点就可以设置在pre【i】+1 ~ i-1上,也就是这个可以作为我们的决策,然后这一段似乎可以单调队列搞出来。当然也可以预处理?

留坑,之后写代码

                

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值