我正在努力解决SPOJ http://www.spoj.com/problems/DOSA的这个问题,这也是一些采访的问题。
我的逻辑是从给定数组中获取满足[i]> i(0基于索引)的元素,因为其他元素总是需要更改。
现在从这些选定元素中找到最长的严格增加子序列,最终答案是阵列计算LIS的原始长度
例如:
原始阵列是:1 7 10 2 20 22
根据a [i]> i计算的新阵列是1 7 10 20 22
现在,这个数组的LIS是5
所以,最终的答案是6-5 = 1
但它给出了错误的答案,任何人都可以指出我逻辑错误的地方。
编辑: 问题陈述 : Lalith准备吃饭,他面前有N dosas,他们的价格由整数序列a1,a2,a3 ...... an表示。
他决定以不同的方式吃饭。你可以用任何正整数代替任何dosa的价格。
必须更换多少价格(整数)才能使结果序列严格增加?
示例输入: 6
1 7 10 2 20 22
示例输出: 1
答案 0 :(得分:3)
你的推理可能有点瑕疵。
考虑以下示例:
10
2 3 4 2 5 6 7 8 9 10
在这里,答案是4(一个需要更改前4个输入),但根据原始海报的逻辑,如果我们剥离:
A[i] less than or equals i
我们将会这样做得到一个残留的数字列表:
2 3 4 5 6 7 8 9 10
如果LIS直接应用于它,显然会得到1的答案(整个序列严格增加,而你只丢弃原始数组中的A [3])
我的方法如下:
尝试构建LIS。也就是说,保持一个数组A [i],使得A [i] =在增加的子序列中最低的第i个项目到目前为止发现 ALSO 遵守其在输入数组中的索引的规律A [i]的值与A [i-1]的指数有差异,使得:
它们各自值之间的差异是> =原始数组中它们的索引差异。如果情况并非如此,那么不幸的是,人们不能在它们之间挤入积分值。
作为一种特殊情况,如果i为0,即它是LIS数组中的第一项,那么它的值必须是>它在输入数组中的索引(你的逻辑 在这里适用)
对于每个项目,二进制搜索最大项目,该项目小于满足上述第1点的当前输入项目 AND 。人们总是可以像这样进行二分搜索,因为如果前提适用于某个值,那么它递归地保持 ALL 值小于当前正在考虑的二进制搜索值。
我通过这种方法传递测试用例。
[编辑] :添加更多解释,因为评论部分不会允许详细评论。
让LIS []成为我们维护的LIS。然后在处理所有 Dosas之后,最终答案= N - size(LIS)
现在,挑战归结为找到如何创建和维护这个数组 - > LIS,效率太高了。它可以在O(N ^ 2)中完成,但是对于大的N会超时,可能具有高达10 ^ 6的值。我们将尝试在O(N * log(N))
中解决它我提出以下不变量:
让LIS [i] = 2元组(对)包含Dosa的价格,该价格仅是(最小可能值)高于LIS [i-1]处的Dosa值并且其指数差异"与LIS [i-1]的Dosa小于或等于"价格差异"与Dosa在LIS [i-1]
即,如果: LIS [i-1] =对(a,b),其中a = Dosa的值,b =原始输入数组中的索引
然后必须坚持:
如果LIS [i] =对(u,v),其中u = Dosa的值,v =原始输入数组中的索引
然后以下内容应始终成立:
u> a(即LIS [i]中的Dosa价格必须严格大于LIS [i-1]的Dosa价值。为什么?嗯,这就是我们想要的第一个,不要我们?一个严格增加的子序列)
你 - a≥v - b(现在,你可能需要思考一下为什么必须这样做)
考虑一个矛盾。让我们说,你 - 一个< v - b。 那么你无法唯一适合原始数组中索引b和a之间的Dosas。因为它需要至少一个重复的Dosa by Pigeon Hole Principle。
现在,上述属性非常适合二进制搜索。为什么? 在尝试将当前正在考虑的Dosa与其(Dosa值,原始数组索引)对值(例如,(u,v))放在某个位置的LIS时,我们必须:
当前Dosa值>你(因为我们想要严格增加子序列)
他们的指数之间的差异应该小于或等于他们的Dosa值之间的差异(如上面#2所述)
如果这不成立,那么我们确信以下任何一种情况都是正确的:
当前Dosa值≤u或
当前Dosa和Dosa之间在二分搜索位置(值v)<1的索引差异。他们各自的Dosa价值差异
如果它是#1,那么我们显然需要在二分搜索中搜索左侧分区(因为我们已经走得太远了)
如果是#2,那么即使当前的Dosa值>呃,那么即使走右路,让我们说二元搜索项目的Dosa值是u + Delta,那么它的高度必须至少为v + Delta,因此它无法做到通过继续向右行进,使指数差<&=高度差。因此,我们必须停止并搜索左侧分区。
[暂停。如果还不清楚,请再读一遍。
[编辑] : SPOILER - 添加工作代码(滚动显示)
[抱歉,我无法在此处添加代码而未获取&#34;您的帖子似乎包含格式不正确的代码&#34;错误。所以,把ideone.com链接]
此处的示例代码:http://ideone.com/tPkUWk
[编辑]:我不想破坏其他人,因此我将代码设为私有。