查找具有最大值的路径,其中T平方值可以加倍

时间:2018-02-15 08:37:34

标签: java recursion dynamic-programming

给定大小为N * N的方阵,其中每个单元与特定成本相关联。路径被定义为特定的细胞序列,其从左上角的细胞开始仅向右或向下移动并在右下角的细胞上结束。我们希望找到具有最大价值的路径。现在让事情变得更有趣:你也有T代币。您可以使用标记将当前方块上的值加倍。您只能在任何给定的方格上使用一个标记。

这就是我解决问题第一部分的方法。

public static long pathWithMaxCost(int[][] n, int tokens) {
    int[][] arr = new int[n.length][n[0].length];

    // starting position
    arr[arr.length - 1][0] = n[arr.length - 1][0];

    // first column
    for (int i = arr.length - 2; i >= 0; i--) {
        arr[i][0] = arr[i + 1][0] + n[i][0];
    }

    // last row
    for (int i = 1; i < arr[0].length; i++) {
        arr[arr.length - 1][i] = arr[arr.length - 1][i - 1] + n[arr.length - 1][i];
    }

    for (int i = arr.length - 2; i >= 0; i--) {
        for (int j = 1; j < arr[0].length; j++) {
            arr[i][j] = Math.max(arr[i][j - 1], arr[i + 1][j]) + n[i][j];

        }
    }

    return arr[0][arr[0].length - 1];
}

现在我该如何处理令牌部分,T平方值可以翻倍?

3 个答案:

答案 0 :(得分:2)

static long pathWithMaxCostHash(int[][] n, int x, int y, int tokkens) {
    if (x < 0 || x >= n.length || y < 0 || y >= n[0].length)
        return -1;
    String key = x + ":" + y + ":" + tokkens;

    if (map.containsKey(key))
        return map.get(key);

    if(x==n.length-1&&y==0) {
        if (tokkens > 0 && n[x][y] > 0) {
            map.put(key,(long)n[n.length-1][0]*2);
            return 2*n[n.length-1][0];

        }
        map.put(key,(long)n[n.length-1][0]);
        return n[n.length-1][0];

    }

    //without picking double
    long val = n[x][y]
            + Math.max(pathWithMaxCostHash(n, x + 1, y, tokkens), pathWithMaxCostHash(n, x, y - 1, tokkens));
    //with picking double
    if (tokkens > 0 && n[x][y] > 0) {
        long val2 = 2 * n[x][y] + Math.max(pathWithMaxCostHash(n, x + 1, y, tokkens - 1),
                pathWithMaxCostHash(n, x, y - 1, tokkens - 1));
        val2 = Math.max(val, val2);
        map.put(key, val2);
        return val2;
    }

    map.put(key, val);
    return val;

}

答案 1 :(得分:1)

T添加另一个维度,因此对单元格的一般检查将是:

m[y][x][t] = max(
  2 * n[y][x] + m[y-1][x][t-1],
  2 * n[y][x] + m[y][x-1][t-1],
  n[y][x] + m[y-1][x][t],
  n[y][x] + m[y][x-1][t]
)
for all y,x,t

让我们考虑边缘情况:

// first element
if x + y == 0:
  m[y][x][0] = n[y][x]
  m[y][x][1] = 2 * n[y][x]
  m[y][x][t] = -Infinity, for t > 1

// first row
if y == 0:
  m[y][x][t] = max(
    2 * n[y][x] + m[y][x-1][t-1],
    n[y][x] + m[y][x-1][t]
  )

// first column
if x == 0:
  m[y][x][t] = max(
    2 * n[y][x] + m[y-1][x][t-1],
    n[y][x] + m[y-1][x][t]
  )

答案 2 :(得分:0)

我会给你一个递归方法,猜猜你可以用这个来找出基于动态编程的解决方案。 用0的

初始化你的dp 2d数组
function: pathWithMaxCost(int x,int y,int tokens, int arr[][],int dp[][])
    if(dp[x][y]) return dp[x][y];
    few boundary conditions here...
    return dp[x][y]=max(arr[x][y]+pathWithMaxCost(x,y+1,tokens,arr), arr[x][y]+pathWithMaxCost(x+1,y,tokens,arr), (arr[x][y]*2)+pathWithMaxCost(x,y+1,tokens-1,arr), (arr[x][y]*2)+pathWithMaxCost(x+1,y,tokens-1,arr))