微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 使用动态规划在矩阵中的最大遍历成本

假设我在 Java中有一个m x n矩阵.

我想从第一列到最后一列找到最大遍历代价.每个值代表所产生的成本.我被允许沿着矩阵上,下,右方向行进.每个单元格只能访问一次.允许从列的顶部单元到底部的转换,反之亦然.

为了简单起见,请考虑以下矩阵:

2 3 17
4 1 -1
5 0 14

如果我应该找到最大成本,我的答案是46(2→5→4→1→3→0→14→17).

我已经尝试使用动态方法使用以下递归关系来解决这个问题:

maxCost(of destination node) = max{ maxCost(at neighbouring node 1),maxCost(at neighbouring node 2),maxCost(at neighbouring node 3) } + cost(of destination node)

在这种情况下,它会像:

maxCost(17) = max{ maxCost(3),maxCost(-1),maxCost(14) } + 17;

因为每个单元格被允许被访问一次,所以我明白我需要维护一个相应的m×n isVisiting矩阵.但是,我不知道如何维护isVisiting矩阵.当计算maxCost(3)时,矩阵将被修改;但是对于maxCost(-1)和maxCost(14),我将需要其初始状态(将丢失).

我的方法是否正确的这个问题?此外,我不知道我的功能应该如何.
(这是我第一次尝试动态编程).

解决方法

这是一个艰难的一个.请注意,由于您的路径不能重复访问的细胞,您的可能的路径将具有“蛇”的行为,例如:

这个想法是在f [j] [i]中存储在单元格(j,i)上结束的路径的最大长度.现在让我们说,我们要从f [j] [i-1]转换到f [j’] [i].那么我们可以直接选择从单元格(j,i)到单元格(j’,i),或者我们可以从单元格(j,i)边缘边缘因此,f [j] [i]的更新可以计算为:

哪里

这里a是给定的数组.

现在的问题是如何有效地计算sum(a [j..j’] [i],否则运行时将为O(m ^ 3n),您可以通过使用临时变量tmp_sum来求解(a [ j.j’] [i]),当你增加j时,你会递增.算法的运算符将是O(m ^ 2 n).

以下是一个示例实现:

package stackoverflow;

public class Solver {

    int m,n;
    int[][] a,f;

    public Solver(int[][] a) {
        this.m = a.length;
        this.n = a[0].length;
        this.a = a;
    }

    void solve(int row) {
        f = new int[m][n];
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                f[i][j] = Integer.MIN_VALUE;

        for (int i = 0; i < n; ++i) {
            int sum = 0;
            for (int j = 0; j < m; ++j)
                sum += a[j][i];
            for (int j1 = 0; j1 < m; ++j1) {
                int tmp_sum = 0;
                boolean first = true;
                for (int j2 = j1; j2 != j1 || first; j2 = (j2+1)%m) {
                    if (first)
                        first = false;
                    tmp_sum += a[j2][i];
                    int best_sum = Math.max(tmp_sum,sum - tmp_sum +a[j1][i]+a[j2][i]);
                    if (j1 == j2)
                        best_sum = a[j1][i];
                    int prev = 0;
                    if (i > 0)
                        prev = f[j1][i-1];
                    f[j2][i] = Math.max(f[j2][i],best_sum + prev);
                }
            }
        }

        System.out.println(f[row][n-1]);
    }

    public static void main(String[] args) {
        new Solver(new int[][]{{2,3,17},{4,1,-1},{5,14}}).solve(0); //46
        new Solver(new int[][]{{1,1},{-1,-1}}).solve(0); //2
    }
}

原文地址:https://www.jb51.cc/java/124923.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐