bzoj 2654 && bzoj 3675 总结

本文分享了两道算法竞赛题目的神奇解法。第一题利用二分搜索调整边权重,确保最小生成树中有指定数量的特定类型边。第二题通过二分常数项优化动态规划,使序列分割满足特定条件。这些技巧展示了算法设计的巧妙与深度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做到了两道(我感觉)思路比较神的题,总结一下。
注:以下两道题我都没有用文中所述方法A过。

1. bzoj 2654

首先如果直接求MST,不能保证有恰好KKK条白边。
而贪心显然是错的。
可以这样想:如果题目里要求是恰好有000条白边,我们可以让所有白边的代价增加+inf⁡+\inf+inf. 如果要求白边最多,可以让白边代价增加−inf⁡-\infinf. 那既然这样的话,MST中白边的数量一定随着给白边增加的权值单调。因此可以二分,直到有KKK条白边即可。最后答案减去K×增加的权值K\times 增加的权值K×.
好神啊www %%%cls
这道题非常重要,希望自己永远也不要忘记这道题。

2. bzoj 3675

正解是斜率优化dp. 但这不是本文的重点。
如果只是斜率优化不搞点有意思的新东西也太无聊了吧!23333
从网上看到的神做法:
首先dpdpdp还是要的:假设dp[i]dp[i]dp[i]表示序列前iii个数分割成若干段的最大得分,则枚举最外层的一次划分dp[i]=max⁡j=1i(s[i]−s[j])s[j]dp[i]=\max^{i}_{j=1} (s[i]-s[j])s[j]dp[i]=maxj=1i(s[i]s[j])s[j], s[j]s[j]s[j]为权值的前缀和。但是这样无法保证最优解能分成KKK段。行吧那我们假设dpdpdp方程长成了这样: dp[i]=max⁡j=1i(s[i]−s[j])s[j]+Cdp[i]=\max^{i}_{j=1} (s[i]-s[j])s[j]+Cdp[i]=maxj=1i(s[i]s[j])s[j]+C, CCC为常数。显然C→+inf⁡C \rightarrow +\infC+infdpdpdp会自然而然地分成nnn段,反之C→−inf⁡C\rightarrow -\infCinf时会分成1段。因此可以二分CCC, 当分的段数达到KKK时,就是答案。最后减去C×KC\times KC×K.
这样做应该是过不了的,但是至少能为我们提供一种思路。
如果在这个算法的基础上加上斜率优化应该就差不多能过了,时间复杂度O(nlog⁡W)O(n\log W)O(nlogW), WWW为值域。这样KKK如果也是1e51e51e5应该也能过了。
(其实我是通过这题才看懂的上一题23333)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值