algorithm - 以最佳方式减少序列

标签 algorithm

我们得到一个 a 序列,其中包含 n 个数字。序列 a减少定义为替换元素 a[i]a[i+1]使用 max(a[i],a[i+1])

每个缩减操作都有一个定义为 max(a[i],a[i+1]) 的成本。经过n-1归约后得到长度为1的序列。

现在我们的目标是打印给定序列 a 的最佳缩减成本,使得长度为 1 的结果序列具有最小成本。

例如:

1

2

3

Output :

5

O(N^2) 的解决方案是微不足道的。有什么想法吗?

编辑1: 人们问我的想法,所以我的想法是成对地遍历序列,并为每一对检查成本,最后减少成本最低的对。

1 2 3
 2 3     <=== Cost is 2

所以将上面的序列减少到

2 3

现在再次遍历序​​列,我们得到成本为 3

2 3
 3       <=== Cost is 3

所以总成本是2+3=5

以上算法是O(N^2)。这就是为什么我要求一些更优化的想法。

最佳答案

O(n) 解决方案:

高级:

基本思想是重复合并小于其邻居 nsnl 的任何元素 e 与其最小的邻居 ns 。这产生了最小的成本,因为合并的成本和结果都是 max(a[i],a[i+1]),这意味着没有合并可以使元素比当前更小,因此,e 最便宜的可能合并是 ns,并且该合并不会增加任何其他可能合并的成本。

这可以通过单遍算法来完成,方法是将数组中的元素堆栈按降序排列。我们将当前元素与其两个相邻元素(一个位于堆栈顶部)进行比较,并执行适当的合并,直到完成。

伪代码:

stack = empty
for pos = 0 to length
  // stack.top > arr[pos] is implicitly true because of the previous iteration of the loop
  if stack.top > arr[pos] > arr[pos+1]
    stack.push(arr[pos])
  else if stack.top > arr[pos+1] > arr[pos]
    merge(arr[pos], arr[pos+1])
  else while arr[pos+1] > stack.top > arr[pos]
    merge(arr[pos], stack.pop)

Java代码:

Stack<Integer> stack = new Stack<Integer>();
int cost = 0;
int arr[] = {10,1,2,3,4,5};
for (int pos = 0; pos < arr.length; pos++)
  if (pos < arr.length-1 && (stack.empty() || stack.peek() >= arr[pos+1]))
    if (arr[pos] > arr[pos+1])
      stack.push(arr[pos]);
    else
      cost += arr[pos+1]; // merge pos and pos+1
  else
  {
    int last = Integer.MAX_VALUE; // required otherwise a merge may be missed
    while (!stack.empty() && (pos == arr.length-1 || stack.peek() < arr[pos+1]))
    {
      last = stack.peek();
      cost += stack.pop(); // merge stack.pop() and pos or the last popped item
    }
    if (last != Integer.MAX_VALUE)
    {
      int costTemp = Integer.MAX_VALUE;
      if (!stack.empty())
        costTemp = stack.peek();
      if (pos != arr.length-1)
        costTemp = Math.min(arr[pos+1], costTemp);
      cost += costTemp;
    }
  }
System.out.println(cost);

关于algorithm - 以最佳方式减少序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15214183/

相关文章:

c - 我用牛顿法求平方根的逻辑有什么问题?

algorithm - 生成具有固定位数的随机数的最有效方法

algorithm - 智胜旅行推销员算法

algorithm - 包含 While 循环的算法的时间复杂度

python-3.x - 如何比较嵌套结构?

c - 霍斯普尔算法

algorithm - 应用马斯特定理 f(n) = 2^n

c++ - 记忆化的递归阶乘函数?

javascript - Tic-Tac-Toe 中的 Minimax 没有返回正确的值

计算最小除数的两个替代函数的性能