这是一些编程竞赛的问题(我不确切知道它属于哪个编程竞赛,我在一年前看到过)。问题如下:
有N栋建筑物,每栋建筑物都有自己的高度(不一定是唯一的)
{h1,h2,h3,...,hn}
我们必须让所有相同高度的建筑物都说h。
允许的操作是:
每个建筑物都需要相关费用来移除/添加单位高度。假设c(i)是移除/增加建筑物单位高度的成本。各自的费用如下:
{c1,c2,c3,...,cn}
假设我们有足够的高度(单位),我们必须找到使所有建筑物具有相同高度所需的最低成本。
输入: 第一行将指定N建筑物的数量。 (1 <= N <= 100000)。 第二条输入线将用于建筑物的高度。
{h1,h2,h3,...,hn}
第三行输入将给出成本数组
{c1,c2,c3.....,cn}
输出
输出将只是所需的最低成本。
示例输入:
3
2 1 3
10 1000 1
示例输出
12
说明:将所有建筑物的高度设为1,因此费用为 10 *(2-1)+ 1000 *(1-1)+ 1 *(3-1)即12。
我知道蛮力方法是O(n ^ 2)。
我认为的蛮力方法如下:
无论常见高度是多少,都必须来自
{h1,h2,h3,....,hn}
即。 h必须等于h(i)中的任何一个。 现在检查每个h(i)我可以用O(n ^ 2)计算答案。
可以更快地完成吗?
答案 0 :(得分:2)
O(n log(n))解决方案:
设h(i)表示第i个建筑物的高度,让c(i)表示第i个建筑物的成本。
现在使用此递归:
Cost_of_Increase(i)= Cost_of_Increase(i-1)+(h(i)-h(i-1))*(第(i-1)个建筑物到第P(n)个建筑物的成本总和)
请注意,在上述递归中,i和i-1的顺序是根据P的顺序,即排序顺序。
现在让Cost_of_decrease(i)表示如果我们使所有高度超过第i个建筑物的建筑物等于SORTED ARRAY P中第i个建筑物的高度,即Cost_of_decrease(i)如果我们建造建筑物P(1),P(2),... P(i-2),P(i-1)等于P(i)建筑物的高度。
为此使用此递归:
Cost_of_decrease(i)= Cost_of_decrease(i + 1)+(h(i + 1)-h(i))*(P(1)建筑物到P(i-1)建筑物的成本总和)
因此,使所有建筑物的高度等于P(i)建筑物的总成本为:
Cost_of_Increase(i)+ Cost_of_decrease(i)。
一旦我们对所有建筑物都有这个,只需检查成本最小的那个,这就是答案。
希望它有所帮助!
答案 1 :(得分:1)
在算法结束后,对所有建筑物的高度执行ternary search或使用hill climbing算法。对于每个高度,您可以计算线性时间的成本,因此总体复杂度将为O(N * log(H)),其中H是可能的最大结果高度。
编辑:这是一个适合你的伪代码片段(这是一种类似爬坡的方法)
typedef long long ll;
ll get_cost(int h) {
if (h < 0 || h > MAX_HEIGHT) {
return MAX_VAL; // some unreachable positive value
}
...
}
int main() {
...
int current = 0;
int leftp, rightp;
ll cv, lv, rv;
ll step = SOME_BIG_ENOUGH_VALUE;
while (step > 0) {
leftp = current - step;
rightp = current + step;
cv = get_cost(current);
lv = get_cost(leftp);
rv = get_cost(rightp);
if (cv <= rv && cv <= lv) {
step /= 2;
} else if (lv < rv) {
current = leftp;
} else {
current = rightp;
}
}
...
}