二维阵列-DP的最大和

时间:2019-02-12 08:24:25

标签: algorithm dynamic-programming

给出一个带有权重的2D数组,找到2D数组的最大和,条件是我们只能从一行中选择一个元素,并且不能选择所选元素下的元素(此条件应对所有元素都成立被选中)。我们还可以看到sum包含的元素等于行数。

如果arr [i] [j]是任何选定的元素,那么我无法选择arr [i + 1] [j]。同样,从每一行中只能选择一个元素。例如,如果选择arr [i] [1],则无法选择arr [i] [2或3或..]

编辑-我尝试使用DP解决它。 拿了一个二维数组DP DP [i] [j] = max(arr [i + 1] [k],其中k = 1到n,k!= j)+ arr [i] [j] 然后执行此操作以构建DP矩阵,最后循环计算最大值。 但是我认为当我这样处理时,复杂度很高。请帮忙!

输入矩阵-

1 2 3 4 
5 6 7 8 
9 1 4 2 
6 3 5 7

输出- 27

1 个答案:

答案 0 :(得分:2)

class Solution {
    private static int maximumSum(int[][] mat){
        int rows = mat.length;
        int cols = mat[0].length;
        int[] ans = new int[cols];
        int[] index = new int[cols];
        int max_val = 0;

        for(int i=0;i<cols;++i){
            ans[i] = mat[0][i];
            index[i] = i;
            max_val = Math.max(max_val,ans[i]); // needed for 1 row input
        }

        for(int i=1;i<rows;++i){
            int[] temp  = new int[cols];
            for(int j=0;j<cols;++j){
                temp[j] = ans[j];
                int max_row_index = -1;
                for(int k=0;k<cols;++k){
                    if(k == index[j]) continue;
                    if(max_row_index == -1 || mat[i][k] > mat[i][max_row_index]){
                        max_row_index = k;
                    }
                }
                temp[j] += mat[i][max_row_index];
                index[j] = max_row_index;
                max_val = Math.max(max_val,temp[j]);
            }
            ans = temp;
        }     

        return max_val;
    }

    public static void main(String[] args) {        
        int[][] arr = {
            {1,2,3,4},
            {5,6,7,8},
            {9,1,4,2},
            {6,3,5,7}
        };

        System.out.println(maximumSum(arr));
    }
}

输出:

27

算法:

  • 在这里让我们采用自上而下的方法。我们从头到尾地将行保持在ans数组中。

  • 让我们通过示例进行锻炼。

案例:

{1,2,3,4},
{5,6,7,8},
{9,1,4,2},
{6,3,5,7}
  • 对于第一行,ans就是[1,2,3,4]
  • 对于第二行,我们为每个[5,6,7,8]123遍历4,跳过每个索引的列下方。例如,对于1,我们跳过下面的5,并在所有列中取最大值,然后将其添加到1中。其他元素也一样。 因此,现在ans数组看起来像[9, 10, 11, 11]
  • 现在,我们为[9, 10, 11, 11]和下一行[9,1,4,2]进行锻炼,依此类推。为此,我们得到[13, 19, 20, 20],对于最后一行[6,3,5,7],我们得到[20, 26, 27, 26],其中27是最高值和最终答案。
  • 时间复杂度: O(n 3 ,空间复杂度: O(m)其中m是列。

更新#1:

通过维护,您可以将复杂度从 O(n 3 降低到 O(n 2 每行2个最大索引。这将始终有效,因为即使1个最大的索引与j的当前索引temp[j]相同,另一个最大索引也将始终提供最大值。感谢 @MBo 的建议。我留给读者练习。

更新#2:

我们还需要维护在最后一行中选择了哪个元素的索引。 请记住这一点,因为我们可以准确地判断当前行的路径。