最近做到了两道(我感觉)思路比较神的题,总结一下。
注:以下两道题我都没有用文中所述方法A过。
1. bzoj 2654
首先如果直接求MST,不能保证有恰好KKK条白边。
而贪心显然是错的。
可以这样想:如果题目里要求是恰好有000条白边,我们可以让所有白边的代价增加+inf+\inf+inf. 如果要求白边最多,可以让白边代价增加−inf-\inf−inf. 那既然这样的话,MST中白边的数量一定随着给白边增加的权值单调。因此可以二分,直到有KKK条白边即可。最后答案减去K×增加的权值K\times 增加的权值K×增加的权值.
好神啊www %%%cls
这道题非常重要,希望自己永远也不要忘记这道题。
2. bzoj 3675
正解是斜率优化dp. 但这不是本文的重点。
如果只是斜率优化不搞点有意思的新东西也太无聊了吧!23333
从网上看到的神做法:
首先dpdpdp还是要的:假设dp[i]dp[i]dp[i]表示序列前iii个数分割成若干段的最大得分,则枚举最外层的一次划分dp[i]=maxj=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]=maxj=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→+infC \rightarrow +\infC→+inf时dpdpdp会自然而然地分成nnn段,反之C→−infC\rightarrow -\infC→−inf时会分成1段。因此可以二分CCC, 当分的段数达到KKK时,就是答案。最后减去C×KC\times KC×K.
这样做应该是过不了的,但是至少能为我们提供一种思路。
如果在这个算法的基础上加上斜率优化应该就差不多能过了,时间复杂度O(nlogW)O(n\log W)O(nlogW), WWW为值域。这样KKK如果也是1e51e51e5应该也能过了。
(其实我是通过这题才看懂的上一题23333)