查找可以挑选的最大苹果,确保在时间T到达右下角的单元格

问题描述

您从给定网格的左上角单元格开始。有些细胞有壁,有些 你可以走路,有些牢房里有苹果。您有时间限制= T,并且您应该至少在T时间之前到达右下角的单元格。找 您可以收集的最大苹果数量。您无法访问手机 两次。 N,M,T

我尝试了很多想法,其中最有前途的是-重新定位问题,因为找到最短的到达目的地的时间至少收集了X个苹果。然后,我们可以对苹果数量进行二进制搜索。 但是我无法确定最近6个小时以来的解决方案。 “你不能两次拜访一个牢房。”这是我的问题。

任何其他想法或提示都会受到赞赏。

解决方法

您尝试过backtracking吗?像这样吗?

// Heuristic: Manhattan distance to end
function dist(y,x,n,m){
  return n - y + m - x - 2;
}

function getNext(i,j,m){
  const ways = [];
  if (i + 1 < n)
    ways.push([i+1,j]);
  if (i > 0)
    ways.push([i-1,j]);
  if (j + 1 < m)
    ways.push([i,j+1]);
  if (j > 0)
    ways.push([i,j-1]);
  return ways;
}

function f(M,T){
  const WALL = 2;
  const n = M.length;
  const m = M[0].length;
  const visited = new Array(n);
  for (let i=0; i<n; i++)
    visited[i] = new Array(m).fill(0);
  let best = 0;
  
  function backtrack(i,t,k){
    if (i == n-1 && j == m-1){
      best = Math.max(best,k + M[i][j]);
      return;
    }
 
    for (const [ii,jj] of getNext(i,m)){
      if (!visited[ii][jj] &&
        M[ii][jj] != WALL &&
        t + dist(ii,jj,m) <= T){
        visited[ii][jj] = 1;
        backtrack(ii,t + 1,k + M[i][j]);
        visited[ii][jj] = 0
      }
    }
  }
  
  backtrack(0,0);
  return best;
}

var N = 8;
var M = 8;
var T = 14;

var matrix = new Array(N);
for (let i=0; i<N; i++)
  matrix[i] = new Array(M).fill(0);
// Apples
matrix[5][5] = 1;
matrix[5][6] = 1;
// Walls
matrix[5][7] = 2;
matrix[5][4] = 2;
matrix[4][4] = 2;
matrix[4][5] = 2;
  
console.log(f(matrix,T));

matrix[5][4] = 0;

console.log(f(matrix,T));

,

鉴于这些约束,您可以使用一个简单的递归函数来解决问题。

solve(i,steps,vis)为函数,其中(i,j)为当前坐标,time为剩余时间,vis为当前访问的节点集。答案将是solve(0,T,[])
简单的递归将是(使用伪代码):

def solve(i,vis):
    if (i<0 or i>=n or j<0 or j>=m) return -1
    if ((i,j) in vis) return -1
    if (cell[i][j] == WALL) return -1
    if (t==0){
        if (i==n-1 and j==m-1) return cell[i][j]
        else return -1
    }
    if (i==n-1 and j==m-1) return cell[i][j]

    max_here = cell[i][j]
    temp = max(solve(i,j+1,t-1,vis+(i,j)),solve(i,j-1,solve(i+1,t- 
               1,solve(i-1,j)))  #assuming movement in 4 directions
    if (temp==-1) return -1   # since none of the neighbours lead to destination
    return max_here+temp