Algorithm 动态规划:在网格中找到和最大的矩形

Algorithm 动态规划:在网格中找到和最大的矩形,algorithm,dynamic-programming,maximize,Algorithm,Dynamic Programming,Maximize,我遇到了下面的动态规划问题 你有一个包含负数的整数网格。找到数字总和最大的矩形 你知道怎么做整个矩阵吗 我对单个数组进行了求解,所以我基本上遵循了最长递增子质量的原理,但只对连续数进行了求解 def array_largest_block(sequence) len = sequence.size parents = [nil]*len my_largest = sequence largest = sequence.max for index in (1...len)

我遇到了下面的动态规划问题

你有一个包含负数的整数网格。找到数字总和最大的矩形

你知道怎么做整个矩阵吗

我对单个数组进行了求解,所以我基本上遵循了最长递增子质量的原理,但只对连续数进行了求解

def array_largest_block(sequence)
  len = sequence.size
  parents = [nil]*len
  my_largest = sequence
  largest = sequence.max

  for index in (1...len)
    if my_largest[index] < my_largest[index] + my_largest[index - 1]
      my_largest[index] = my_largest[index] + my_largest[index - 1]
      parents[index] = index - 1
      largest = [largest, my_largest[index]].max
    end
  end

  end_index_of_largest_block = my_largest.find_index(largest)
  i = end_index_of_largest_block
  res = []
  res << sequence[i]
  while !parents[i].nil?
    i = parents[i]
    res << sequence[i]
  end
  return {l_sum: largest, start: i, end: end_index_of_largest_block}
end
所以我的想法是

求矩阵中每个平方的和,即1x1平方 保存最大值以获得可能的答案 从可能的最小矩形开始运行相同的操作,并计算所有这些操作,直到找到最大值,即DB部分。 有什么想法吗?或者如果你们不知道精确解,我应该看哪种DP类型的算法?

这可以在^3中完成,其中N是矩阵的大小

基本上,您可以选择矩形的左栏和右栏,然后使用预计算的和以线性时间扫描行

int totalBestSum = -10000000;
for (int leftCol = 1; leftCol <= N; leftCol++)
   for (int rightCol = leftCol; rightCol <= N; rightCol++)
   {
      int curSum = 0, curBestSum = -10000000;
      for (int row = 1; row <= N; row++) {
         int rowSum = sumBetween(leftCol, rightCol, row);
         curSum += rowSum;
         if (curSum > curBestSum) curBestSum = curSum;
         if (curSum < 0) curSum = 0;                   
      }

      if (curBestSum > totalBestSum) totalBestSum = curBestSum;
   } 
int sumBetween(int leftCol, int rightCol, int row)
{
    return sum[row][rightCol] - sum[row][leftCol - 1];
}
要计算和数组,请执行以下操作:

这可以在^3中完成,其中N是矩阵的大小

基本上,您可以选择矩形的左栏和右栏,然后使用预计算的和以线性时间扫描行

int totalBestSum = -10000000;
for (int leftCol = 1; leftCol <= N; leftCol++)
   for (int rightCol = leftCol; rightCol <= N; rightCol++)
   {
      int curSum = 0, curBestSum = -10000000;
      for (int row = 1; row <= N; row++) {
         int rowSum = sumBetween(leftCol, rightCol, row);
         curSum += rowSum;
         if (curSum > curBestSum) curBestSum = curSum;
         if (curSum < 0) curSum = 0;                   
      }

      if (curBestSum > totalBestSum) totalBestSum = curBestSum;
   } 
int sumBetween(int leftCol, int rightCol, int row)
{
    return sum[row][rightCol] - sum[row][leftCol - 1];
}
要计算和数组,请执行以下操作:


看起来像是复制品,但还是看这里:

可以在^3上执行此操作


你到底为什么要使用“NP完全”标签呢?:D

看起来像是重复的,但请看这里:

可以在^3上执行此操作


你到底为什么要使用“NP完全”标签呢?:D

heh,我认为动态编程问题是NP完全的,就像knap-sack…嘿,我认为动态编程问题是NP完全的,就像knap-sack。。。