P2672 [NOIP2015 普及组] 推销员
aaaaaaaawsl · · 个人记录
证明以下贪心策略是正确的
- 先按住户的疲劳值从大到小排序,
X = i 时的答案即为
考虑在排完序的住户中选择前
下面的住户都是指排完序的住户。
如果存在更大的疲劳值选择方案,那么一定是后面某些点被选了,同时放弃了前面的某些点。
给出方案,唯一一种比选择前
核心代码
ans = max(sum[i] + per[i], sum[i - 1] + suf[i]); // sum[i] 是前i个住户的疲惫值的和,per[i] 是前i个住户的最大距离,suf[i] 是后面的住户的(距离疲惫值)最大值。
证明:
-
在只换一个的情况下,由于都固定放弃疲惫值最小的这个,总疲惫值减少的值是一定的,加上剩下中最大的值一定比加上其他值更优。当然,得出的新疲惫值是强制把新选择的住户的距离当做最远距离。
如果新选择的住户的距离不是去掉第
X 个住户后的最远距离,那么有前X 个住户中选择出的最远距离大于这个住户的距离,并且前X 个住户的疲惫值都大于这个住户的疲惫值,那么这种选择一定劣于选择前X 个住户,在统计答案的时候不会统计上。 -
如果选择继续尝试扩大,那么假设放弃了第
X - 1 个住户,选择了第Z 个住户,首先Z 的距离疲惫值小于Y 。如果Z 的距离小于Y ,那么Z 的距离不能贡献价值,因此Z 的距离疲惫值就更小于Y ,所以不优。如果Z 的距离大于Y ,那么现在选中Z 后的总疲惫值就是\sum_{j = 1}^{X - 2} val_j + val_{Y} + val_{Z} + len_Z \times 2 显然不选
Y 选上第X - 1 个住户更优,因为val_{x-1}>val_{Y} ,此时价值又是\sum_{j = 1}^{X - 1} val_j + val_{Z} + len_Z \times 2 因为
val_{Z} + len_Z \times 2 < val_{Y} + len_Y \times 2 -
如果第一次扩大的时候不选距离疲惫值最大的住户,那么到第二次扩大时的情况等效于上一条所述。
综上,这种贪心策略才是正确的。单是题解区没有完整的证明,要不不证明,要不只证明浅显的一部分。
时间复杂度严格
我的代码-目前最优解