Prob_Solve 板


LINE

题目:给定一含有 n 个整数的阵列 A ,找出不相交的 k 个子阵列其总和最大。 也就是要找 k 组索引对 (b1, e1), ... (bk, ek), bi < ei 且 ei < b_{i+1} 使得 A[bi...ei] 的总和最大。 出处: http://www.lintcode.com/en/problem/maximum-subarray-iii/ 这问题理论上线性时间可解,可以参考 http://goo.gl/llwDs8http://arxiv.org/pdf/1410.2847.pdf 但是方法有点复杂。 首先,我们可以把问题稍微简化一点,把所有为零的元素去掉,头尾的 负数去掉,然後把所有同号的子阵列合并为一个元素。 在不失一般性的情况下可以假设阵列中有多於 k 个正整数 所以我们可以假设下列性质 所有偶数的 i, A[i] 为正 所有奇数的 i, A[i] 为负 (阵列是从 0 起算) A[0] 和 A[n-1] 皆为正 且 n > 2k - 1 。 因为是要算子阵列的总和,可以使用 prefix sum 的技巧。 令 P[i] = A[0..i] 的总和,那麽 A[i..j] 的总和就可以用 P[j] - P[i - 1] 来求(假设 P[-1] = 0),又因为 A 阵列是正负交替出现的, P 阵列会满足 对於所有偶数的 i, P[i-1] < P[i] > P[i+1] 如果 i-1, i+1 合法 所以这问题可以转换成以下问题 给定一含有 n 个整数的阵列 P , P[i-1] < P[i] > P[i+1] 找出 k 组索引对 (b1, e1), ... (bk, ek), bi < ei 且 ei < b_{i+1} 使得 P[ei] - P[bi] 总和最大 (P[-1] = 0) 可以把 P[i] 当成股票在第 i 天的价格,允许作 k 次交易,求最大的获利。 出处: http://codeforces.com/problemset/problem/391/F3 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/ 同样这题也是线性时间可解的 http://www.tachenov.name/2016/best-time-to-buy-and-sell-stock-iv/ https://maskray.me/blog/2015-03-27-leetcode-best-time-to-buy-and-sell-stock-iv 我觉得这个解法有点难懂,所以推敲了很久,以下是我思考的结果: 考虑两组不相交索引对 (b, e) 和 (b', e'), e < b' 其在 P 中相对应的值为 [l, h] 和 [l', h'] 亦即 l = P[b], h = P[e], l' = P[b'] 和 h' = P[e'] (l代表低点, h 代表高点) 只考虑 l < h 和 l' < h' 的情况,因为买高卖低没意义。 如果 l >= l' ,那麽我们不需要考虑 b 跟 e' 之後的索引配对的情况,因 为可以用 l' 来配对,所以我们可以忽略所有(b, e) 对 (b', e')之後的影响。 如果 l < l' ,那 l 就有可能会跟 e' 之後的索引配对,所以(b, e)要保留。 我们可以一个一个考虑索引对 (b, b+1) for b = -1, 1, ... n - 2 然後用一个 stack 来维护可跟之後元素结合的索引对。 此 stack 会满足一个单调性: 令 (b1, e1), ..., (bt, et) 为 stack 中的索引对(t为顶端),这 些索引对必不相交,且 ei < b_{i+1}。 令 [l1, h1], ..., [lt, ht] 为索引在 P 中相对应的值,则必满足 [li, hi] 严格包含 [l_{i+1}, h_{i+1}] 如果把 [l, h] 想成区间 而维护这个性质也不难,当新进来一组索引对 (b, e),其起点 b 必在所 有在 stack 中的索引对之後。令其对应的值为 [l = P[b], h = P[e]] 如果 lt >= l, 那麽 stack 顶端的索引对以後不会需要了,把此索引对 从 stack 中移除,把 [lt, ht] 丢到一个 list L 里面,以备最後挑选。 重复此动作直到 lt < l 为止。 当 lt < l 时,有两种情况: ht > h: 亦即 [l, h] 是被 [lt, ht] 包含的,那就把 [l, h] 放到 stack 里面。 ht <= h: 这情况比较麻烦,因为 [lt, ht] 和 [l, h] 没有包含关系。 此时我们可以假装把 [lt, ht] 和 [l, h] 合并为 [lt, h]。 因为 lt < l ,所有可以跟 l 配对的都不会比跟 lt 配对 来的好,所以并不会漏掉可以配对的情况。 但是这样作会漏掉把 [lt, ht] 和 [l, h] 分别选取的情况。 不过我们知道分别选择会得到 (ht - lt) + (h - l) = (h - lt) + (ht - l) 也就是说分别选择的话,可多得到 ht - l 。 所以如果 ht - l > 0 的话,我们可以把一个假的区间 [l, ht] 丢到 L 中,其值为(ht - l),以备最後挑选。 重复此动作直到 ht > h。 当把所有索引对处理完之後,把 stack 中所有的索引对其相对应的值区间 都丢到 L 中,从 L 里面挑出值最大的 k 个就是答案了。 感觉还是有点复杂,不知道有没有比较简单的想法。 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 65.96.6.117
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Prob_Solve/M.1457054558.A.D5F.html
1F:推 stimim: 是最多找k个还是一定要找k个,如果一定要找k个,那就算赚 03/04 14:55
2F:→ stimim: 的数量不足k个,赔钱还是要买满k次 03/04 14:56
3F:→ FRAXIS: 因为我原本问题的假设是至少有 k 个正整数 所以转化过後 03/04 19:29
4F:→ FRAXIS: 就一定可以找到 k 个.. 如果是直接考虑股票买卖问题的话 03/04 19:30
5F:→ FRAXIS: 应该是最多可以找 k 个 03/04 19:30
6F:推 stimim: 不过不到k个正数也没差就是了,取前k大的加起来就是答案 03/04 20:26
7F:推 johnathan717: 推 03/04 21:10
※ 编辑: FRAXIS (65.96.6.117), 03/05/2016 06:34:21







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP