考虑到我们有一大堆黄金和小偷希望得到最大的黄金。小偷可以拿金来获得最大值,
1)从连续的麻袋中取出黄金。
2)小偷应从所有麻袋中取出相同数量的金。
N Sacks 1 <= N <= 1000
M量的金0 <= M <= 100
示例输入1:
3 0 5 4 4 4
输出: 16
说明: 4是他从麻袋3到6中取出的最小值,以获得最大值16。
示例输入2: 2 4 3 2 1
输出: 8
说明: 2是他从麻袋1到4中取得的最小值,以获得最大值8。
我使用从数组中减去值并将转换点从负数转为正数来解决问题,但这并不能解决问题。
编辑:OP提供的代码,用于查找索引:
int temp[6];
for(i=1;i<6;i++){
for(j=i-1; j>=0;j--) {
temp[j] = a[j] - a[i];
}
}
for(i=0;i<6;i++){
if(temp[i]>=0) {
index =i;
break;
}
}
答案 0 :(得分:3)
从每个袋子中取出的最佳金量(TBAG)等于某些袋子的重量。让我们按顺序将候选人的索引放在一个堆栈中。
当我们遇到更重的重量(比堆栈包含)时,它肯定会继续&#34;良好的序列&#34;,所以我们只需将其索引添加到堆栈中。
当我们遇到较轻的重量(比堆叠顶部)时,它会打破一些好的序列&#34;我们可以从堆栈中删除较重的候选者 - 他们以后没有机会成为TBAG。移除堆栈顶部直到满足较轻的重量,在此过程中计算可能被盗的总和。
请注意,堆栈始终包含严格增加权重序列的索引,因此我们不需要在堆栈顶部(中间AG)的索引之前考虑项目来计算被盗总和(稍后将考虑使用另一个AG值)。
for idx in Range(Sacks):
while (not Stack.Empty) and (Sacks[Stack.Peek] >= Sacks[idx]): //smaller sack is met
AG = Sacks[Stack.Pop]
if Stack.Empty then
firstidx = 0
else
firstidx = Stack.Peek + 1
//range_length * smallest_weight_in_range
BestSUM = MaxValue(BestSUM, AG * (idx - firstidx))
Stack.Push(idx)
now check the rest:
repeat while loop without >= condition
每个项目都被按下并弹出一次,因此线性时间和空间复杂。
P.S。我觉得我在另一种表述中见过这个问题......
答案 1 :(得分:1)
我现在看到两种不同的方法:
天真的方法:对于数组中的每对索引(i,j),计算区间(i,j)中数组的最小值m(i,j)然后计算得分(i,j)= | j-i + 1 | * m(i,j)。然后取所有对(i,j)的最高分。
- &GT; O(n ^ 3)的复杂性。
不太天真的方法:
计算数组的值集
对于每个值,计算它可以获得的最高分数。为此,您只需要对数组的所有值进行一次迭代。例如,当您的样本输入为[3 0 5 4 4 4]并且您正在查看的当前值为3时,它将为您提供12分。(您将首先找到值3,这要归功于第一个指数,然后由于指数从2到5而得分为12。
取最大值在步骤2中找到的所有值。
- &GT;复杂度在这里是O(n * m),因为你必须在步骤2中进行最多m次,而步骤2可以在O(n)中完成。
也许有更好的复杂性,但我还没有线索。