我对这个算法问题有疑问:
数据计划的成本为X.我们得到一个(未排序的)数组 整数,Y(1 <= Y <= 1e6)。对于每个整数Y,如果Y> X,然后总计 成本增加X +(Y - X)*(Y - X)。否则,总费用是 增加X.请找到值X,以便总成本为 最小化。
首先想到的是,O(N^2)
方法很简单且易于编码,但对于大型输入数组(即2e5)来说效率非常低。
我的方法是使用二进制搜索。作为前驱,我对数组进行排序。然后我想象基于数组中的整数在条形图中画一条线 - 该线将图表分成两部分:下半部分<= X
中的每个元素和另一半{{1}中的元素}。
让大于> X
的元素产生的费用为X
,其余费用为H
。
让L
表示我猜测的下限,BOT
表示我猜测的上限。
我逻辑的伪代码:
TOP
示例:
WHILE BOT <= TOP:
DO
X = (BOT+TOP)/2;
// Compute H and L based on X
// ...
ans = MIN(ans,H+L)
IF H == L:
BREAK;
ELSE IF H > L:
BOT = X + 1;
ELSE:
TOP = X - 1;
DONE
PRINT ANS
答案应为70,因为我们可以选择6。
对数组进行排序:
1 2 9 5 7 6 3 4 2 2
因此,6(8)+ 7 + 15 = 70
我的实际代码如下所示:
Elements: 1 2 2 2 3 4 5 6 7 9
Cost: 6 6 6 6 6 6 6 6 7 15
我用这种方法得到了错误的答案(它传递了示例测试用例)。虽然我觉得我的逻辑可能有缺陷,但我不能产生任何反例。有人可以告诉我一个更好的解决方案吗?
答案 0 :(得分:2)
获得反例的好方法如下。
考虑一些小数字的例子,例如1 2 3 4 5 6 7 8 9 10
。
也许X
与算法的最佳位置位于序列右端附近(运行程序后的实际答案:84)。
现在大量增加所有值,例如10001 10002 10003 10004 10005 10006 10007 10008 10009 10010
。
显然,现在正方形与实际值相比无关紧要,并且您的算法会声称X
的最佳位置靠近序列的中心(运行程序后的实际答案:10085)。
不过,应该清楚的是,如果第一个示例的解为X
,则第二个示例为X + 10000
。
更一般地说,您的解决方案声称这两个小组&#39;总和必须尽可能接近,但划分为这些确切的组是一个不受实际证据支持的主张。
要真正解决问题,或许可以证明总费用函数f(x)
是convex,或者换句话说,有限差异f(x+1)-f(x)
不会减少。
如果确实如此,则可以使用ternary search查找解决方案,或使用有限差异f(x+1)-f(x)
而非实际f(x)
进行二元搜索。