Taxicab in San Francisco
JavaScript (ES6), 228 212 200 194 bytes

a=&gt;w=&gt;(B=1/0,(F=(r,p,s,b=a[p])=&gt;p-a.length+1?1/b&amp;&amp;([...a[p]='RDUL'].map((c,d)=&gt;d|p%w&lt;w-1&amp;&amp;d-3|p%w&amp;&amp;F(r+c,P=p+[1,w,-w,-1][d],s+1+Math.abs(b-a[P]))),a[p]=b):R=s&gt;B?R:s&lt;B?(B=s,r):R+' '+r)('',0,0),R)


Input

One-dimensional array a and width w in currying syntax (a)(w)

Output

A space-separated list of solutions such as "DRDRRDR DRDRDRR"

Formatted and commented

a =&gt; w =&gt; (                            // given an array 'a' and a width 'w'
  B = 1 / 0,                           // B = best score so far, initialized as +Infinity
  (                                    //
    F = (                              // F = recursive function with:
      r,                               //   - r = current path (string)
      p,                               //   - p = current position in grid
      s,                               //   - s = current score
      b = a[p]                         //   - b = backup of current cell
    ) =&gt;                               //
    p - a.length + 1 ?                 // if we haven't reached our destination:
      1 / b &amp;&amp; (                       //   if the current cell is valid:
        [...a[p] = 'RDUL']             //     invalidate the current cell
        .map((c, d) =&gt;                 //     for each possible direction:
          d | p % w &lt; w - 1 &amp;&amp;         //       check right boundary
          d - 3 | p % w &amp;&amp;             //       check left boundary
          F(                           //       do a recursive call with:
            r + c,                     //         - new direction appended to the path
            P = p + [1, w, -w, -1][d], //         - updated position
            s + 1 + Math.abs(b - a[P]) //         - updated score
          )                            //
        ),                             //
        a[p] = b                       //     restore current cell value
      )                                //
    :                                  // else:
      R = s &gt; B ?                      //   if the current score is worse than B:
        R                              //     keep the previous solution
      : s &lt; B ?                        //   if the current score is better than B:
        (B = s, r)                     //     update best score / store path as new solution
      : R + ' ' + r                    //   if it's just as good: append path to solution
  )('', 0, 0),                         // initial call to F with r = '', p = 0, s = 0
  R                                    // return solution
)                                      //


Test cases



let f =

a=&gt;w=&gt;(B=1/0,(F=(r,p,s,b=a[p])=&gt;p-a.length+1?1/b&amp;&amp;([...a[p]='RDUL'].map((c,d)=&gt;d|p%w&lt;w-1&amp;&amp;d-3|p%w&amp;&amp;F(r+c,P=p+[1,w,-w,-1][d],s+1+Math.abs(b-a[P]))),a[p]=b):R=s&gt;B?R:s&lt;B?(B=s,r):R+' '+r)('',0,0),R)

console.log(f([
  0, 3, 0, 0, 0,
  0, 2, 0, 2, 0,
  0, 0, 0, 3, 0
])(5));

console.log(f([
  3
])(1));

console.log(f([
  11, 11, 11,
  11, 11, 11,
  11, 11, 11
])(3));

console.log(f([
  7, 8, 1, -1, 0,
  4, 4, 6, -1, 7,
  3, 4, 4,  2, 8,
  2, 5, 2, -1, 2
])(5));