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

前端之家收集整理的这篇文章主要介绍了java – 使用动态规划在矩阵中的最大遍历成本前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我在 Java中有一个m x n矩阵.

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

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

  1. 2 3 17
  2. 4 1 -1
  3. 5 0 14

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

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

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

在这种情况下,它会像:

  1. 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).

以下是一个示例实现:

  1. package stackoverflow;
  2.  
  3. public class Solver {
  4.  
  5. int m,n;
  6. int[][] a,f;
  7.  
  8. public Solver(int[][] a) {
  9. this.m = a.length;
  10. this.n = a[0].length;
  11. this.a = a;
  12. }
  13.  
  14. void solve(int row) {
  15. f = new int[m][n];
  16. for (int i = 0; i < m; ++i)
  17. for (int j = 0; j < n; ++j)
  18. f[i][j] = Integer.MIN_VALUE;
  19.  
  20. for (int i = 0; i < n; ++i) {
  21. int sum = 0;
  22. for (int j = 0; j < m; ++j)
  23. sum += a[j][i];
  24. for (int j1 = 0; j1 < m; ++j1) {
  25. int tmp_sum = 0;
  26. boolean first = true;
  27. for (int j2 = j1; j2 != j1 || first; j2 = (j2+1)%m) {
  28. if (first)
  29. first = false;
  30. tmp_sum += a[j2][i];
  31. int best_sum = Math.max(tmp_sum,sum - tmp_sum +a[j1][i]+a[j2][i]);
  32. if (j1 == j2)
  33. best_sum = a[j1][i];
  34. int prev = 0;
  35. if (i > 0)
  36. prev = f[j1][i-1];
  37. f[j2][i] = Math.max(f[j2][i],best_sum + prev);
  38. }
  39. }
  40. }
  41.  
  42. System.out.println(f[row][n-1]);
  43. }
  44.  
  45. public static void main(String[] args) {
  46. new Solver(new int[][]{{2,3,17},{4,1,-1},{5,14}}).solve(0); //46
  47. new Solver(new int[][]{{1,1},{-1,-1}}).solve(0); //2
  48. }
  49. }

猜你在找的Java相关文章