当前位置: 首页 > 知识库问答 >
问题:

稳定合并两个阵列以最大化相邻元素的乘积

仲孙鸿飞
2023-03-14

以下是一个采访问题,我无法回答的复杂性低于指数复杂性。虽然这似乎是一个DP问题,但我无法形成基本案例并正确分析它。感谢您的帮助。

将为您提供两个大小为“n”的数组。您需要稳定地合并这些数组,以便在新数组中使连续元素的乘积之和最大化。

例如

A={2,1,5}

B={3,7,9}

稳定合并A={a1,a2,a3}和B={b1,b2,b3}将创建一个包含2*n个元素的数组C。例如,通过合并(稳定的)A和B,假设C={b1,a1,a2,a3,b2,b3}。那么和=b1*a1 a2*a3 b2*b3应该是最大值。

共有3个答案

唐修明
2023-03-14

我的解决办法相当简单。我只是探索所有可能的稳定合并。遵循工作C程序:

#include<iostream>

using namespace std;

void find_max_sum(int *arr1, int len1, int *arr2, int len2, int sum, int& max_sum){
  if(len1 >= 2)
    find_max_sum(arr1+2, len1-2, arr2, len2, sum+(arr1[0]*arr1[1]), max_sum);
  if(len1 >= 1 && len2 >= 1)
    find_max_sum(arr1+1, len1-1, arr2+1, len2-1, sum+(arr1[0]*arr2[0]), max_sum);
  if(len2 >= 2)
    find_max_sum(arr1, len1, arr2+2, len2-2, sum+(arr2[0]*arr2[1]), max_sum);
  if(len1 == 0 && len2 == 0 && sum > max_sum)
    max_sum = sum;
}

int main(){
  int arr1[3] = {2,1,3};
  int arr2[3] = {3,7,9};
  int max_sum=0;
  find_max_sum(arr1, 3, arr2, 3, 0, max_sum);
  cout<<max_sum<<endl;
  return 0;
}
冀永寿
2023-03-14

对于A={a1, a2,..., an}, B={b1, b2,..., bn},

定义DP[i,j]为{ai,…,an}和{bj,…,bn}之间的最大稳定合并和。

(一)

DP[n 1, n 1]=0, DP[n 1, k]=bk*bk 1... bn-1*bn, DP[k, n 1]=ak*ak 1... an-1*an.

DP[n,k]=max{an*bk bk 1*bk 2..bn-1*bn,DP[n,k 2]bk*bk 1}

DP[k,n]=max{ak*bn ak 1*ak 2..an-1*an,DP[k2,n]ak*ak 1}

DP[i,j]=max{DP[i2,j]ai*ai1,DP[i,j2]bi*bi1,DP[i1,j1]ai*bi}。

然后返回DP[1,1]。

说明:在每一步中,你必须考虑3个选项:从剩下的A中取前2个元素,从剩下的B中取第一个2个元素,或者从A和B中取两个元素(因为你不能改变A和B的顺序,你必须从A和B中取第一个)。

淳于宏伯
2023-03-14

让我们定义c[i, j]作为相同问题的解,但是数组从i开始到左结束。和j以右结尾。所以c[0,0]将给出原始问题的解。

c[i,j]包括。

  1. MaxValue=最大值

现在定义这个DP的最优子结构

c[i,j] = if(NeedsPairing) { left[i]*right[j] } + Max { c[i+1, j], c[i, j+1] }

在此代码中更详细地捕获了它。

if (lstart == lend)
{
    if (rstart == rend)
    {
        nodeResult = new NodeData() { Max = 0, Child = null, NeedsPairing = false };
    }
    else
    {
        nodeResult = new NodeData()
        {
            Max = ComputeMax(right, rstart),
            NeedsPairing = (rend - rstart) % 2 != 0,
            Child = null
        };
    }
}
else
{
    if (rstart == rend)
    {
        nodeResult = new NodeData()
        {
            Max = ComputeMax(left, lstart),
            NeedsPairing = (lend - lstart) % 2 != 0,
            Child = null
        };
    }
    else
    {
        var downLef = Solve(left, lstart + 1, right, rstart);

        var lefResNode = new NodeData()
        {
            Child = Tuple.Create(lstart + 1, rstart),
        };

        if (downLef.NeedsPairing)
        {
            lefResNode.Max = downLef.Max + left[lstart] * right[rstart];
            lefResNode.NeedsPairing = false;
        }
        else
        {
            lefResNode.Max = downLef.Max;
            lefResNode.NeedsPairing = true;
        }

        var downRt = Solve(left, lstart, right, rstart + 1);

        var rtResNode = new NodeData()
        {
            Child = Tuple.Create(lstart, rstart + 1),
        };

        if (downRt.NeedsPairing)
        {
            rtResNode.Max = downRt.Max + right[rstart] * left[lstart];
            rtResNode.NeedsPairing = false;
        }
        else
        {
            rtResNode.Max = downRt.Max;
            rtResNode.NeedsPairing = true;
        }

        if (lefResNode.Max > rtResNode.Max)
        {
            nodeResult = lefResNode;
        }
        else
        {
            nodeResult = rtResNode;
        }
    }
}

我们使用记忆来防止再次解决子问题。

Dictionary<Tuple<int, int>, NodeData> memoization = new Dictionary<Tuple<int, int>, NodeData>();

最后我们使用NodeData。要追溯路径的子对象。

 类似资料:
  • 我看到一个问题,要求它找到所有相邻子阵列的最小值。例如,对于数组A=[1,2,3],答案将是一个包含[1,2,3,1,2,1]的数组B<怎么做- 我所做的是,构建了一个段树,但是它不包含所有连续子数组的最小值。 我也不认为我可以使用“脱钩”,因为我不必在特定长度的子数组中找到最小值。 那么,我如何获得所有连续子阵列(B阵列)的最小值?

  • 在R中,我可以在矩阵和(共形)向量之间进行分段乘法,例如: 矩阵的每一行都与相应的向量元素相乘。我也可以对维度大于2的数组做同样的事情: 同样,每一行都与相应的向量元素相乘。我能为3d阵列和2d矩阵做类似的事情吗?我只想让数组中的每个子矩阵都按元素乘以一个矩阵。

  • 我喜欢将具有相同行的两个矩阵的列的所有可能组合相乘。这意味着两个矩阵,例如和将生成包含元素的3x4矩阵。(和表示从1到3的行,表示从1到4的列) 我已经创建了一个例子,可以完成这项工作,但正在寻找没有for循环的优雅解决方案。 这里a是3x3矩阵,b是3x4矩阵,comb通过乘以各个列给出3x12矩阵的输出。我正在寻找优雅的解决方案,可以推广到这样的乘法到两个以上的矩阵。

  • 有没有一种方法可以在小于O(n^2)的时间内做到这一点。 O(nlogn)还是O(n)?

  • 问题内容: 谁能告诉我如何在ojAlgo中将两个矩阵的对应元素相乘?寻找块函数 问题答案: 有几种方法可以做到这一点。这是一种选择: matrixA.operateOnMatching(MULTIPLY,matrixB).supplyTo(matrixC); MULTIPLY来自静态导入​​的位置(org.ojalgo.function.constant.PrimitiveMath)。

  • SameGame示例 让我们以一个SameGame板为例。 如果两个块有一个共同的边,则它们是相邻的。组是由至少两个块组成的集合,所有块都是相同类型的,并且每个块都与组的至少一个其他成员相邻。当鼠标悬停在作为组的一部分的块上时,整个组应在视觉上突出显示。 举个矩阵的例子: 鼠标悬停怎么找一套? 我想过递归,但老实说,我不知道该怎么做。BFS似乎是我可以做的事情,但对于这样一个“简单”的事情来说,它