text:
Q: Bomb dropping algorithm I have an n x m matrix consisting of non-negative integers. For example:
2 3 4 7 1
1 5 2 6 2
4 3 4 2 1
2 1 2 4 1
3 1 3 4 1
2 1 4 3 2
6 9 1 6 4

"Dropping a bomb" decreases by one the number of the target cell and all eight of its neighbours, to a minimum of zero.
x x x
x X x
x x x

What is an algorithm that would determine the minimum number of bombs required to reduce all the cells to zero?
B Option (Due to me not being a careful reader)
Actually the first version of problem is not the one I'm seeking answer for. I didn't carefully read whole task, there's additional constraints, let us say:
What about simple problem, when sequence in row must be non-increasing:
8 7 6 6 5 is possible input sequence
7 8 5 5 2 is not possible since 7 -> 8 growing in a sequence.
Maybe finding answer for "easier" case would help in finding solution for harder one.
PS: I believe that when we have several same situations require minimum bombs to clear upper line, we choose one that use most bombs on "left side" of the row. Still any proof that might be correct?

A: This would be a greedy approach:

*

*Calculate a "score" matrix of order n X m, where score[i][j] is the total deduction of points in the matrix if position (i,j) is bombed. (Max score of a point is 9 and min score is 0)

*Moving row wise, find and pick the first position with highest score (say (i,j)).

*Bomb (i,j). Increase bomb count.

*If all elements of the original matrix are not zero, then goto 1.
I have my doubts that this is the optimal solution though.
Edit:
The Greedy approach I posted above, while it works, most probably doesn't give us the optimal solution. So I figured should add some elements of DP to it.
I think we can agree that at any point of time, one of the positions with the highest "score" (score[i][j] = total deduction of points if (i,j) is bombed) must be targeted. Starting with this assumption, here's the new approach:
NumOfBombs(M): (returns the minimum number of bombings required)

*

*Given a Matrix M of order n X m. If all elements of M are zero, then return 0.

*Calculate the "score" matrix M.
Let the k distinct positions P1,P2,...Pk (1 <= k <= n*m), be the positions in M with the highest scores.

*return (1 + min( NumOfBombs(M1), NumOfBombs(M2), ..., NumOfBombs(Mk) ) )
where M1,M2,...,Mk are the resulting matrices if we bomb positions P1, P2, ..., Pk respectively.
Also, if we want the order of positions to nuke in addition to this, we would have to keep track of the results of "min".

A: You can represent this problem as integer programming problem. (this is just one of possible solutions to approach this problem)
Having points:
a b c d
e f g h
i j k l
m n o p

one can write 16 equations where for point f for example holds
f <= ai + bi + ci + ei + fi + gi + ii + ji + ki

minimaised over sum of all indexes and integer solution.
Solution is of course sum of this indexes.
This can be further simplified by setting all xi on boundaries  0, so you end up having 4+1 equation in this example.
Problem is that there is no trivial algorhitm for solving such problems. tI am not expert on this, but solving this problem as linear programming is NP hard.

A: This is a partial answer, I'm trying to find a lower bound and upper bound that could be the possible number of bombs.
In 3x3 and smaller board, the solution is trivially always the largest numbered cell.
In boards larger than 4x4, the first obvious lower bound is the sum of the corners:
*2* 3  7 *1*
 1  5  6  2
 2  1  3  2
*6* 9  6 *4*

however you arrange the bomb, it is impossible to clear this 4x4 board with less than 2+1+6+4=13 bombs.
It has been mentioned in other answers that placing the bomb on the second-to-corner to eliminate the corner is never worse than placing the bomb on the corner itself, so given the board:
*2* 3  4  7 *1*
 1  5  2  6  2
 4  3  4  2  1
 2  1  2  4  1
 3  1  3  4  1
 2  1  4  3  2
*6* 9  1  6 *4*

We can zero the corners out by placing bombs on the second-to-corner to give a new board:
 0  1  1  6  0
 0  3  0  5  1
 2  1  1  1  0
 2  1  2  4  1
 0  0  0  0  0
 0  0  0  0  0
 0  3  0  2  0

So far so good. We need 13 bombs to clear the corners.
Now observe the number 6, 4, 3, and 2 marked below:
 0  1  1 *6* 0
 0  3  0  5  1
 2  1  1  1  0
*2* 1  2 *4* 1
 0  0  0  0  0
 0  0  0  0  0
 0 *3* 0  2  0

There is no way to bomb any two of those cells using a single bomb, so the minimum bomb has increased by 6+4+3+2, so adding to the number of bombs we used to clear the corners, we get that the minimum number of bombs required for this map has become 28 bombs. It is impossible to clear this map with less than 28 bombs, this is the lower bound for this map.
You can use greedy algorithm to establish an upper bound. Other answers have shown that a greedy algorithm produces a solution that uses 28 bombs. Since we've proven earlier that no optimal solution can have less than 28 bombs, therefore 28 bombs is indeed an optimal solution.
When greedy and the method to find the minimal bound I've mentioned above does not converge though, I guess you do have to go back to checking all combinations.
The algorithm for finding the lower bound is the following:

*

*Pick an element with the highest number, name it P.

*Mark all cells two steps away from P and P itself as unpickable.

*Add P to the minimums list.

*Repeat to step 1 until all cells are unpickable.

*Sum the minimums list to get the lower bound.

A: Your new problem, with the nondecreasing values across rows, is quite easy to solve.
Observe that the left column contains the highest numbers. Therefore, any optimal solution must first reduce this column to zero. Thus, we can perform a 1-D bombing run over this column, reducing every element in it to zero. We let the bombs fall on the second column so they do maximum damage. There are many posts here dealing with the 1D case, I think, so I feel safe in skipping that case. (If you want me to describe it, I can.). Because of the decreasing property, the three leftmost columns will all be reduced to zero. But, we will provably use a minimum number of bombs here because the left column must be zeroed.
Now, once the left column is zeroed, we just trim off the three leftmost columns that are now zeroed and repeat with the now-reduced matrix. This must give us an optimal solution since at each stage we use a provably minimum number of bombs.

A: Mathematica Integer Linear Programming using branch-and-bound
As it has already been mentioned, this problem can be solved using integer linear programming (which is NP-Hard). Mathematica already has ILP built in. "To solve an integer linear programming problem Mathematica first solves the equational constraints, reducing the problem to one containing inequality constraints only. Then it uses lattice reduction techniques to put the inequality system in a simpler form. Finally, it solves the simplified optimization problem using a branch-and-bound method." [see Constrained Optimization Tutorial in Mathematica.. ]
I've written the following code that utilizes ILP libraries of Mathematica. It is surprisingly fast.
solveMatrixBombProblem[problem_, r_, c_] :=
 Module[{},
  bombEffect[x_, y_, m_, n_] :=
   Table[If[(i == x || i == x - 1 || i == x + 1) && (j == y ||
        j == y - 1 || j == y + 1), 1, 0], {i, 1, m}, {j, 1, n}];
  bombMatrix[m_, n_] :=
   Transpose[
    Table[Table[
      Part[bombEffect[(i - Mod[i, n])/n + 1, Mod[i, n] + 1, m,
        n], (j - Mod[j, n])/n + 1, Mod[j, n] + 1], {j, 0,
       m*n - 1}], {i, 0, m*n - 1}]];
  X := x /@ Range[c*r];
  sol = Minimize[{Total[X],
     And @@ Thread[bombMatrix[r, c].X >= problem] &&
      And @@ Thread[X >= 0] && Total[X] <= 10^100 &&
      Element[X, Integers]}, X];
  Print["Minimum required bombs = ", sol[[1]]];
  Print["A possible solution = ",
   MatrixForm[
    Table[x[c*i + j + 1] /. sol[[2]], {i, 0, r - 1}, {j, 0,
      c - 1}]]];]

For the example provided in the problem:
solveMatrixBombProblem[{2, 3, 4, 7, 1, 1, 5, 2, 6, 2, 4, 3, 4, 2, 1, 2, 1, 2, 4, 1, 3, 1, 3, 4, 1, 2, 1, 4, 3, 2, 6, 9, 1, 6, 4}, 7, 5]

Outputs

For anyone reading this with a greedy algorithm
Try your code on the following 10x10 problem:
5   20  7   1   9   8   19  16  11  3
17  8   15  17  12  4   5   16  8   18
4   19  12  11  9   7   4   15  14  6
17  20  4   9   19  8   17  2   10  8
3   9   10  13  8   9   12  12  6   18
16  16  2   10  7   12  17  11  4   15
11  1   15  1   5   11  3   12  8   3
7   11  16  19  17  11  20  2   5   19
5   18  2   17  7   14  19  11  1   6
13  20  8   4   15  10  19  5   11  12

Here it is comma-seperated:
5, 20, 7, 1, 9, 8, 19, 16, 11, 3, 17, 8, 15, 17, 12, 4, 5, 16, 8, 18, 4, 19, 12, 11, 9, 7, 4, 15, 14, 6, 17, 20, 4, 9, 19, 8, 17, 2, 10, 8, 3, 9, 10, 13, 8, 9, 12, 12, 6, 18, 16, 16, 2, 10, 7, 12, 17, 11, 4, 15, 11, 1, 15, 1, 5, 11, 3, 12, 8, 3, 7, 11, 16, 19, 17, 11, 20, 2, 5, 19, 5, 18, 2, 17, 7, 14, 19, 11, 1, 6, 13, 20, 8, 4, 15, 10, 19, 5, 11, 12

For this problem, my solution contains 208 bombs. Here's a possible solution (I was able to solve this in about 12 seconds).

As a way to test the results Mathematica is producing, see if your greedy algorithm can do any better.

A: There is a way to reduce this to a simple sub-problem.
There are 2 parts to the explanation, the algorithm, and the reason the algorithm
provides an optimal solution.  The first won't make sense without the second, so I'll
start with the why.
If you think of bombing the rectangle (assume a big rectangle - no edge cases yet)
you can see that the only way to reduce the hollow rectangle of squares on the
perimeter to 0 is to bomb either the perimeter or to bomb the hollow rectangle of
squares just inside the perimeter.  I'll call the perimeter layer 1, and the rectangle inside it layer 2.
An important insight is that there is no point bombing layer 1, because the
"blast radius" you get from doing so is always contained within the blast radius of
another square from layer 2.  You should be able to easily convince yourself of this.
So, we can reduce the problem to finding an optimal way to bomb away the perimeter, then we can repeat that until all squares are 0.
But of course, that won't always find an optimal solution if it's possible to bomb
away the perimeter in a less than optimal fashion, but by using X extra bombs make
the problem of reducing the inner layer simpler by >X bombs.  So, if we call
the permiter layer one, if we place an extra X bombs somewhere in layer 2 (just
inside layer 1), can we reduce the effort of later bombing away layer 2 by more than
X?  In other words, we have to prove we can be greedy in reducing the outer
perimeter.
But, we do know we can be greedy.  Because no bomb in layer 2 can ever be more
efficient in reducing layer 2 to 0 than a strategically placed bomb in layer 3.  And
for the same reason as before - there is always a bomb we can place in layer 3 that
will affect every square of layer 2 that a bomb placed in layer 2 can.  So, it can
never harm us to be greedy (in this sense of greedy).
So, all we have to do is find the optimal way to reduce the permiter to 0 by bombing
the next inner layer.
We are never hurt by first bombing the corner to 0, because only the corner of the inner layer can reach it, so we really have no choice (and, any bomb on the perimeter that can reach the corner has a blast radius contained in the blast radius from the corner of the inner layer).
Once we have done so, the squares on the perimeter adjacent to the 0 corner can only be reached by 2 squares from the inner layer:
0       A       B

C       X       Y

D       Z

At this point the perimeter is effectively a closed 1 dimensional loop, because any bomb will reduce 3 adjacent squares.  Except for some weirdness near the corners - X can "hit" A,B,C,and D.
Now we can't use any blast radius tricks - the situation of each square is symmetric, except for the weird corners, and even there no blast radius is a subset of another.  Note that if this were a line (as Colonel Panic discusses) instead of a closed loop  the solution is trivial.  The end points must be reduced to 0, and it never harms you to bomb the points adjacent to the end points, again because the blast radius is a superset.  Once you have made your endpoint 0, you still have a new endpoint, so repeat (until the line is all 0).
So, if we can optimally reduce a single square in the layer to 0 we have an algorithm (because we have cut the loop and now have a straight line with endpoints).  I believe bombing adjacent to the square with the lowest value (giving you 2 options) such that the highest value within 2 squares of that lowest value is the minimum possible (you may have to split your bombing to manage this) will be optimal but I don't (yet?) have a proof.

A: This greedy solution seems to be correct:
As pointed in comments, it'll fail in 2D. But maybe you may improve it.
For 1D:
   If there is at least 2 numbers you don't need to shoot to the leftmost one because shooting to the second is not worse. So shoot to the second, while first isn't 0, because you have to do it. Move to the next cell. Don't forget about last cell.
C++ code:
void bombs(vector<int>& v, int i, int n){
    ans += n;
    v[i] -= n;
    if(i > 0)
        v[i - 1] -= n;
    if(i + 1< v.size())
        v[i + 1] -= n;
}

void solve(vector<int> v){
    int n = v.size();
    for(int i = 0; i < n;++i){
        if(i != n - 1){
            bombs(v, i + 1, v[i]);
        }
        else
            bombs(v, i, v[i])
    }
}

So for 2D:
  Again: you don't need to shoot in the first row (if there is the second). So shoot to the second one. Solve 1D task for first row. (because you need to make it null). Go down. Don't forget last row.

A: There is no need to transform the problem to linear sub-problems.
Instead use a simple greedy heuristic, which is to bomb the corners, starting with the largest one.
In the given example there are four corners, { 2, 1, 6, 4 }. For each corner there is no better move than to bomb the cell diagonal to the corner, so we know for a fact our first 2+1+6+4 = 13 bombings must be in these diagonal cells. After doing the bombing we are left with a new matrix:
2 3 4 7 1      0 1 1 6 0      0 1 1 6 0     1 1 6 0     0 0 5     0 0 0
1 5 2 6 2      0 3 0 5 1      0 3 0 5 1  => 1 0 4 0  => 0 0 3  => 0 0 0
4 3 4 2 1      2 1 1 1 0      2 1 1 1 0     0 0 0 0     0 0 0     0 0 3
2 1 2 4 1  =>  2 1 2 4 1  =>  2 1 2 4 1     0 0 3 0     0 0 3
3 1 3 4 1      0 0 0 0 0      0 0 0 0 0
2 1 4 3 2      0 0 0 0 0      0 0 0 0 0
6 9 1 6 4      0 3 0 2 0      0 0 0 0 0

After the first 13 bombings we use the heuristic to eliminate 3 0 2 via three bombings. Now, we have 2 new corners, { 2, 1 } in the 4th row. We bomb those, another 3 bombings. We have reduced the matrix to 4 x 4 now. There is one corner, the upper left. We bomb that. Now we have 2 corners left, { 5, 3 }. Since 5 is the largest corner we bomb that first, 5 bombings, then finally bomb the 3 in the other corner. The total is 13+3+3+1+5+3 = 28.

A: This does a breadth-search for the shortest path (a series of bombings) through this "maze" of positions.  No, I cannot prove that there is no faster algorithm, sorry.
#!/usr/bin/env python

M = ((1,2,3,4),
     (2,3,4,5),
     (5,2,7,4),
     (2,3,5,8))

def eachPossibleMove(m):
  for y in range(1, len(m)-1):
    for x in range(1, len(m[0])-1):
      if (0 == m[y-1][x-1] == m[y-1][x] == m[y-1][x+1] ==
               m[y][x-1]   == m[y][x]   == m[y][x+1] ==
               m[y+1][x-1] == m[y+1][x] == m[y+1][x+1]):
        continue
      yield x, y

def bomb(m, (mx, my)):
  return tuple(tuple(max(0, m[y][x]-1)
      if mx-1 <= x <= mx+1 and my-1 <= y <= my+1
      else m[y][x]
      for x in range(len(m[y])))
    for y in range(len(m)))

def findFirstSolution(m, path=[]):
#  print path
#  print m
  if sum(map(sum, m)) == 0:  # empty?
    return path
  for move in eachPossibleMove(m):
    return findFirstSolution(bomb(m, move), path + [ move ])

def findShortestSolution(m):
  black = {}
  nextWhite = { m: [] }
  while nextWhite:
    white = nextWhite
    nextWhite = {}
    for position, path in white.iteritems():
      for move in eachPossibleMove(position):
        nextPosition = bomb(position, move)
        nextPath = path + [ move ]
        if sum(map(sum, nextPosition)) == 0:  # empty?
          return nextPath
        if nextPosition in black or nextPosition in white:
          continue  # ignore, found that one before
        nextWhite[nextPosition] = nextPath

def main(argv):
  if argv[1] == 'first':
    print findFirstSolution(M)
  elif argv[1] == 'shortest':
    print findShortestSolution(M)
  else:
    raise NotImplementedError(argv[1])

if __name__ == '__main__':
  import sys
  sys.exit(main(sys.argv))

A: It seems that a linear programming approach can be very helpful here.
Let Pm x n be the matrix with the values of the positions:

Now let define a bomb matrix B(x, y)m x n,with 1 ≤ x ≤ m, 1 ≤ y ≤ n as below

in such a way that

For example:

So we are looking to a matrix Bm x n = [bij] that

*

*Can be defined as a sum of bomb matrices:

(qij would be then the quantity of bombs we would drop in position pij)

*pij - bij ≤ 0  (to be more succint, let us say it as P - B ≤ 0)
Also, B should minimize the sum .
We can also write B as the ugly matrix ahead:

and since P - B ≤ 0 (which means P ≤ B) we have the following pretty linear inequality system below:

Being qmn x 1 defined as

pmn x 1 defined as

We can say we have a system  being Smn x mn the matrix to be reversed to solve the system. I did not expand it myself but I believe it should be easy to do it in code.
Now, we have a minimum problem which can be stated as

I believe it is something easy, almost trivial to be solved with something like the simplex algorithm (there is this rather cool doc about it). However, I do know almost no linear programming (I will take a course about it on Coursera but it is just in the future...), I had some headaches trying to understand it and I have a huge freelance job to finish so I just give up here. It can be that I did something wrong at some point, or that it can't go any further, but I believe this path can eventually lead to the solution. Anyway, I am anxious for your feedback.
(Special thanks for this amazing site to create pictures from LaTeX expressions)

A: Pólya says "If you can't solve a problem, then there is an easier problem you can solve: find it."
The obvious simpler problem is the 1-dimensional problem (when the grid is a single row). Let's start with the simplest algorithm - greedily bombing the biggest target. When does this go wrong?
Given 1 1 1, the greedy algorithm is indifferent to which cell it bombs first. Of course, the centre cell is better - it zeros all three cells at once. This suggests a new algorithm A, "bomb to minimise the sum remaining". When does this algorithm go wrong?
Given 1 1 2 1 1, algorithm A is indifferent between bombing the 2nd, 3rd or 4th cells. But bombing the 2nd cell to leave 0 0 1 1 1 is better than bombing the 3rd cell to leave 1 0 1 0 1. How to fix that? The problem with bombing the 3rd cell is that it leaves us work to the left and work to the right which must be done separately.
How about "bomb to minimise the sum remaining, but maximise the minimum to the left (of where we bombed) plus the minimum to the right". Call this algorithm B. When does this algorithm go wrong?

Edit: After reading the comments, I agree a much more interesting problem would be the one dimensional problem changed so that the ends join up. Would love to see any progress on that.

A: Here's another idea:
Let's start by assigning a weight to each space on the board for how many numbers would be reduced by dropping a bomb there.  So if the space has a non-zero number, it gets a point, and if any space adjacent to it has a non-zero number, it gets an additional point.  So if there is a 1000-by-1000 grid, we have a weight assigned to each of the 1 million spaces.
Then sort the list of spaces by weight, and bomb the one with the highest weight.  This is getting the most bang for our buck, so to speak.
After that, update the weight of every space whose weight is affected by the bomb.  This will be the space you bombed, and any space immediately adjacent to it, and any space immediately adjacent to those.  In other words, any space which could have had its value reduced to zero by the bombing, or the value of a neighboring space reduced to zero.
Then, re-sort the list spaces by weight.  Since only a small subset of spaces had their weight changed by the bombing, you won't need to resort the whole list, just move those ones around in the list.
Bomb the new highest weight space, and repeat the procedure.
This guarantees that every bombing reduces as many spaces as possible (basically, it hits as few spaces which are already zero as possible), so it would be optimal, except that their can be ties in weights.  So you may need to do some back tracking when there is a tie for the top weight.  Only a tie for the top weight matters, though, not other ties, so hopefully it's not too much back-tracking.
Edit:
Mysticial's counterexample below demonstrates that in fact this isn't guaranteed to be optimal, regardless of ties in weights.  In some cases reducing the weight as much as possible in a given step actually leaves the remaining bombs too spread out to achieve as high a cummulative reduction after the second step as you could have with a slightly less greedy choice in the first step.  I was somewhat mislead by the notion that the results are insensitive to the order of bombings.  They are insensitive to the order in that you could take any series of bombings and replay them from the start in a different order and end up with the same resulting board.  But it doesn't follow from that that you can consider each bombing independently.  Or, at least, each bombing must be considered in a way that takes into account how well it sets up the board for subsequent bombings.

A: I believe that to minimize the amount of bombs you simply need maximize the amount of damage..
for that to happen need to check the area that has the strongest force.. so you first analyze the field with a 3x3 kernel and check where the sum is stronger.. and bomb there.. and do until the field is flat.. for this filed the answer is 28
var oMatrix = [
[2,3,4,7,1],
[1,5,2,6,2],
[4,3,4,2,1],
[2,1,2,4,1],
[3,1,3,4,1],
[2,1,4,3,2],
[6,9,1,6,4]
]

var nBombs = 0;
do
{
    var bSpacesLeftToBomb = false;
    var nHigh = 0;
    var nCellX = 0;
    var nCellY = 0;
    for(var y = 1 ; y<oMatrix.length-1;y++)
        for(var x = 1 ; x<oMatrix[y].length-1;x++)
        {
            var nValue = 0;
            for(var yy = y-1;yy<=y+1;yy++)
                for(var xx = x-1;xx<=x+1;xx++)
                    nValue += oMatrix[yy][xx];

            if(nValue>nHigh)
            {
                nHigh = nValue;
                nCellX = x;
                nCellY = y;
            }

        }
    if(nHigh>0)
    {
        nBombs++;

        for(var yy = nCellY-1;yy<=nCellY+1;yy++)
        {
            for(var xx = nCellX-1;xx<=nCellX+1;xx++)
            {
                if(oMatrix[yy][xx]<=0)
                    continue;
                oMatrix[yy][xx] = --oMatrix[yy][xx];
            }
        }
        bSpacesLeftToBomb = true;
    }
}
while(bSpacesLeftToBomb);

alert(nBombs+'bombs');

A: To minimize the number of bombs, we have to maximize effect of every bomb. To achive this, on every step we have to select the best target. For each point summing it and it's eight neighbours - could be used as an efficiency quantity of bombing this point. This will provide close to optimal sequence of bombs.
UPD: We should also take number of zeros into account, becouse bombin them is inefficiently. In fact the problem is to minimize number of hitted zeros. But we can not know how any step gets us closer to this aim. I agree with idea that the problem is NP-complete. I sugest a greedy approach, which will give an answer close to real.

A: Here is a solution that generalizes the good properties of the corners.
Let's assume that we could find a perfect drop point for a given field, that is, a best way to decrease the value in it. Then to find the minimum number of bombs to be dropped, a first draft of an algorithm could be (the code is copy-pasted from a ruby implementation):
dropped_bomb_count = 0
while there_are_cells_with_non_zero_count_left
  coordinates = choose_a_perfect_drop_point
  drop_bomb(coordinates)
  dropped_bomb_count += 1
end
return dropped_bomb_count

The challenge is choose_a_perfect_drop_point. First, let's define what a perfect drop point is.

*

*A drop point for (x, y) decreases the value in (x, y). It may also decrease values in other cells.

*A drop point a for (x, y) is better than a drop point b for (x, y) if it decreases the values in a proper superset of the cells that b decreases.

*A drop point is maximal if there is no other better drop point.

*Two drop points for (x, y) are equivalent if they decrease the same set of cells.

*A drop point for (x, y) is perfect if it is equivalent to all maximal drop points for (x, y).

If there is a perfect drop point for (x, y), you cannot decrease the value at (x, y) more effectively than to drop a bomb on one of the perfect drop points for (x, y).
A perfect drop point for a given field is a perfect drop point for any of its cells.
Here are few examples:
1 0 1 0 0
0 0 0 0 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0

The perfect drop point for the cell (0, 0) (zero-based index) is (1, 1). All other drop points for (1, 1), that is (0, 0), (0, 1), and (1, 0), decrease less cells.
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0

A perfect drop point for the cell (2, 2) (zero-based index) is (2, 2), and also all the surrounding cells (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), and (3, 3).
0 0 0 0 1
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0

a perfect drop points for the cell (2, 2) is (3, 1): It decreases the value in (2, 2), and the value in (4, 0). All other drop points for (2, 2) are not maximal, as they decrease one cell less. The perfect drop point for (2, 2) is also the perfect drop point for (4, 0), and it is the only perfect drop point for the field. It leads to the perfect solution for this field (one bomb drop).
1 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
1 0 0 0 0

There is no perfect drop point for (2, 2): Both (1, 1) and (1, 3) decrease (2, 2) and another cell (they are maximal drop points for (2, 2)), but they are not equivalent. However, (1, 1) is a perfect drop point for (0, 0), and (1, 3) is a perfect drop point for (0, 4).
With that definition of perfect drop points and a certain order of checks, I get the following result for the example in the question:
Drop bomb on 1, 1
Drop bomb on 1, 1
Drop bomb on 1, 5
Drop bomb on 1, 5
Drop bomb on 1, 5
Drop bomb on 1, 6
Drop bomb on 1, 2
Drop bomb on 1, 2
Drop bomb on 0, 6
Drop bomb on 0, 6
Drop bomb on 2, 1
Drop bomb on 2, 5
Drop bomb on 2, 5
Drop bomb on 2, 5
Drop bomb on 3, 1
Drop bomb on 3, 0
Drop bomb on 3, 0
Drop bomb on 3, 0
Drop bomb on 3, 0
Drop bomb on 3, 0
Drop bomb on 3, 4
Drop bomb on 3, 4
Drop bomb on 3, 3
Drop bomb on 3, 3
Drop bomb on 3, 6
Drop bomb on 3, 6
Drop bomb on 3, 6
Drop bomb on 4, 6
28

However, the algorithm only works if there is at least one perfect drop point after each step. It is possible to construct examples where there are no perfect drop points:
0 1 1 0
1 0 0 1
1 0 0 1
0 1 1 0

For these cases, we can modify the algorithm so that instead of a perfect drop point, we choose a coordinate with a minimal choice of maximal drop points, then calculate the minimum for each choice. In the case above, all cells with values have two maximal drop points. For example, (0, 1) has the maximal drop points (1, 1) and (1, 2). Choosing either one and then calcualting the minimum leads to this result:
Drop bomb on 1, 1
Drop bomb on 2, 2
Drop bomb on 1, 2
Drop bomb on 2, 1
2

A: I had to stop at only a partial solution since I was out of time, but hopefully even this partial solution provides some insights on one potential approach to solving this problem.
When faced with a hard problem, I like to come up with simpler problems to develop an intuition about the problem space. Here, the first step I took was to reduce this 2-D problem into a 1-D problem. Consider a line:
0 4 2 1 3 0 1

Somehow or another, you know you will need to bomb at or around the 4 spot 4 times to get it down to 0. Since left of the spot is a lower number, there is no benefit to bombing the 0 or the 4 over bombing the 2. In fact, I believe (but lack a rigorous proof) that bombing the 2 until the 4 spot goes down to 0 is at least as good as any other strategy to get that 4 down to 0. One can proceed down the line left to right in a strategy like this:
index = 1
while index < line_length
  while number_at_index(index - 1) > 0
    bomb(index)
  end
  index++
end
# take care of the end of the line
while number_at_index(index - 1) > 0
  bomb(index - 1)
end

A couple sample bombing orders:
0 4[2]1 3 0 1
0 3[1]0 3 0 1
0 2[0]0 3 0 1
0 1[0]0 3 0 1
0 0 0 0 3[0]1
0 0 0 0 2[0]0
0 0 0 0 1[0]0
0 0 0 0 0 0 0

4[2]1 3 2 1 5
3[1]0 3 2 1 5
2[0]0 3 2 1 5
1[0]0 3 2 1 5
0 0 0 3[2]1 5
0 0 0 2[1]0 5
0 0 0 1[0]0 5
0 0 0 0 0 0[5]
0 0 0 0 0 0[4]
0 0 0 0 0 0[3]
0 0 0 0 0 0[2]
0 0 0 0 0 0[1]
0 0 0 0 0 0 0

The idea of starting with a number that needs to go down some way or another is an appealing one because it suddenly becomes attainable to find a solution that as some claim to being at least as good as all other solutions.
The next step up in complexity where this search of at least as good is still feasible is on the edge of the board. It is clear to me that there is never any strict benefit to bomb the outer edge; you're better off bombing the spot one in and getting three other spaces for free. Given this, we can say that bombing the ring one inside of the edge is at least as good as bombing the edge. Moreover, we can combine this with the intuition that bombing the right one inside of the edge is actually the only way to get edge spaces down to 0. Even more, it is trivially simple to figure out the optimal strategy (in that it is at least as good as any other strategy) to get corner numbers down to 0. We put this all together and can get much closer to a solution in the 2-D space.
Given the observation about corner pieces, we can say for sure that we know the optimal strategy to go from any starting board to a board with zeros on all corners. This is an example of such a board (I borrowed the numbers from the two linear boards above). I've labelled some spaces differently, and I'll explain why.
0 4 2 1 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

One will notice at the top row really closely resembles the linear example we saw earlier. Recalling our earlier observation that the optimal way to get the top row all down to 0 is to bomb the second row (the x row). There is no way to clear the top row by bombing any of the y rows and no additional benefit to bombing the top row over bombing the corresponding space on the x row.
We could apply the linear strategy from above (bombing the corresponding spaces on the x row), concerning ourselves only with the top row and nothing else. It would go something like this:
0 4 2 1 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 3 1 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 2 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 1 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 0 0 0 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

The flaw in this approach becomes very obvious in the final two bombings. It is clear, given that the only bomb sites that reduce the 4 figure in the first column in the second row are the first x and the y. The final two bombings are clearly inferior to just bombing the first x, which would have done the exact same (with regard to the first spot in the top row, which we have no other way of clearing). Since we have demonstrated that our current strategy is suboptimal, a modification in strategy is clearly needed.
At this point, I can take a step back down in complexity and focus just one one corner. Let's consider this one:
0 4 2 1
4 x y a
2 z . .
1 b . .

It is clear the only way to get the spaces with 4 down to zero are to bomb some combination of x, y, and z. With some acrobatics in my mind, I'm fairly sure the optimal solution is to bomb x three times and then a then b. Now it's a matter of figuring out how I reached that solution and if it reveals any intuition we can use to even solve this local problem. I notice that there's no bombing of y and z spaces. Attempting to find a corner where bombing those spaces makes sense yields a corner that looks like this:
0 4 2 5 0
4 x y a .
2 z . . .
5 b . . .
0 . . . .

For this one, it is clear to me that the optimal solution is to bomb y 5 times and z 5 times. Let's go one step further.
0 4 2 5 6 0 0
4 x y a . . .
2 z . . . . .
5 b . . . . .
6 . . . . . .
0 . . . . . .
0 . . . . . .

Here, it feels similarly intuitive that the optimal solution is to bomb a and b 6 times and then x 4 times.
Now it becomes a game of how to turn those intuitions into principles we can build on.
Hopefully to be continued!

A: For updated question a simple greedy algorithm gives optimal result.
Drop A[0,0] bombs to cell A[1,1], then drop A[1,0] bombs to cell A[2,1], and continue this process downwards. To clean bottom left corner, drop max(A[N-1,0], A[N-2,0], A[N-3,0]) bombs  to the cell A[N-2,1]. This will completely clean up first 3 columns.
With the same approach clean columns 3,4,5, then columns 6,7,8, etc.
Unfortunately this does not help finding solution for the original problem.

"Larger" problem (without "nonicreasing" constraint) may be proven to be NP-hard. Here is sketch of a proof.
Suppose we have a planar graph of degree up to 3. Let's find minimum vertex cover for this graph. According to Wikipedia article this problem is NP-hard for planar graphs of degree up to 3. This could be proven by reduction from Planar 3SAT. And hardness of Planar 3SAT - by reduction from 3SAT. Both these proofs are presented in recent lectures in "Algorithmic Lower Bounds" by prof. Erik Demaine (lectures 7 and 9).
If we split some edges of the original graph (left graph on the diagram), each one with even number of additional nodes, the resulting graph (right graph on the diagram) should have exactly the same minimum vertex cover for original vertices. Such transformation allows to align graph vertices to arbitrary positions on the grid.

If we place graph vertices only to even rows and columns (in such a way that no two edges incident to one vertex form an acute angle), insert "ones" wherever there is an edge, and insert "zeros" to other grid positions, we could use any solution for the original problem to find minimum vertex cover.

A: If you want the absolute optimal solution to clean the board you will have to use classic backtracking, but if the matrix is very big it will take ages to find the best solution, if you want an "possible" optimal solution you can use greedy algorithm, if you need help writing the algorithm i can help you
Come to think of it that is the best way. Make another matrix there you store the points you remove by dropping a bomb there then chose the cell with maximum points and drop the bomb there update the points matrix and continue. Example:
2 3 5 -> (2+(1*3)) (3+(1*5)) (5+(1*3))
1 3 2 -> (1+(1*4)) (3+(1*7)) (2+(1*4))
1 0 2 -> (1+(1*2)) (0+(1*5)) (2+(1*2))

cell value +1 for every adjacent cell with a value higher than 0

A: Well, suppose we number the board positions 1, 2, ..., n x m.  Any sequence of bomb drops can be represented by a sequence of numbers in this set, where numbers can repeat.  However, the effect on the board is the same regardless of what order you drop the bombs in, so really any choice of bomb drops can be represented as a list of n x m numbers, where the first number represents the number of bombs dropped on position 1, the second number represents the number of bombs dropped on position 2, etc.  Let's call this list of n x m numbers the "key".
You could try first calculating all board states resulting from 1 bomb drop, then use these to calculate all board states resulting from 2 bomb drops, etc until you get all zeros.  But at each step you would cache the states using the key I defined above, so you can use these results in calculating the next step (a "dynamic programming" approach).
But depending on the size of n, m, and the numbers in the grid, the memory requirements of this approach might be excessive.  You can throw away all the results for N bomb drops once you've calculated all the results for N + 1, so there's some savings there.  And of course you could not cache anything at the cost of having it take a lot longer -- the dynamic programming approach trades memory for speed.

A: *

*Never bomb border (unless square does not have nonborder neighbour)

*Zero corner.

*To zero corner, drop value of corner one square away diagonaly (the only nonborder neighbour)

*This will create new corners. Go to 2

Edit: did not notice that Kostek suggested almost same approach, so now I make stronger claim:
If corners to clear are chosen to be always on outermost layer, then it is optimal.
In OP's example: dropping 2 (as 1+1 or 2) on anything else than on 5 does not leads to hitting any square that dropping on 5 would hit. So we simply must drop 2 on 5 (and 6 on lower left 1 ...)
After this, there is only one way how to clear (in top left) corner what was originaly 1 (now 0), and that is by dropping 0 on B3 (excel like notation).
And so on.
Only after clearing whole A and E columns and 1 and 7 rows, start clearing one layer deeper.
Consider cleared only those intentionaly cleared, clearing 0 value corners costs nothing and simplifies thinking about it.
Because all bombs dropped this way must be dropped and this leads to cleared fields, it is optimal solution.

After good sleep I realized that this is not true.
Consider
  ABCDE
1 01000
2 10000
3 00000
4 00000

My approach would drop bombs on B3 and C2, when dropping on B2 would be enough

A: Brute Force !
I know it is not efficient, but even if you find a faster algorithm, you can always test against this result to know how accurate it is.
Use some recursion, like this:
void fn(tableState ts, currentlevel cl)
{
  // first check if ts is all zeros yet, if not:
  //
  // do a for loop to go through all cells of ts,
  // for each cell do a bomb, and then
  // call:
  // fn(ts, cl + 1);

}

You can make this more efficient by caching, if different way lead to same result, you shouldn't repeat the same steps.
To elaborate:
if bombing cell 1,3,5 leads to the same result as bombing cell 5,3,1 , then, you shouldn't re-do all the next steps again for both cases, only 1 is enough, you should store somewhere all table states and use its results.
A hash of table stats can be used to do fast comparison.

A: Here's my solution.. I won't write it out in code yet since I don't have time, but I believe this should produce an optimal number of moves each time - though I'm not sure how efficient it would be at finding the points to bomb.
Firstly, as @Luka Rahne stated in one of the comments, the order in which you bomb is not important- only the combination.
Secondly, as many others have stated, bombing 1-off the diagonal from the corners is optimal because it touches more points than the corners.
This generates the basis for my version of the algorithm:
We can bomb the '1-off from the corners' first or last, it doesn't matter (in theory)
We bomb those first because it makes later decisions easier (in practice)
We bomb the point which affects the most points, while simultaneously bombing those corners.
Let's define Points Of Resistance to be the points in the board with the most non-bombable points + largest number of 0's around them
non-bombable points can be defined as points which don't exist in our current scope of the board we're looking at.
I'll also define 4 bounds which will handle our scope:
Top=0, Left=0, Bottom=k,right=j.
(values to start)
Finally, I'll define optimal bombs as bombs which are dropped on points that are adjacent to points of resistance and are touching (1) the highest valued point of resistance and (2) the largest number of points possible.
Regarding the approach- it's obvious we're working from the outside in. We will be able to work with 4 'bombers' at the same time.
The first points of resistance are obviously our corners. The 'out of bound' points are not bombable (there are 5 points outside the scope for each corner). So we bomb the points diagonally one off the corners first.
Algorithm:

*

*Find the 4 optimal bomb points.

*If a bomb point is bombing a resistance point which is touching 2 bounds (i.e. a corner), bomb till that point is 0. Otherwise, bomb each until one of the points of resistance touching the optimal bomb point is 0.

*for each bound:
if(sum(bound)==0) advance bound

repeat until TOP=BOTTOM and LEFT=RIGHT
I will try to write the actual code later

A: I got 28 moves as well. I used two tests for the best next move: first the move producing the minimum sum for the board. Second, for equal sums, the move producing the maximum density, defined as:
number-of-zeros / number-of-groups-of-zeros

This is Haskell. "solve board" shows the engine's solution. You can play the game by typing "main", then enter a target point, "best" for a recommendation, or "quit" to quit.
OUTPUT:
*Main> solve board
[(4,4),(3,6),(3,3),(2,2),(2,2),(4,6),(4,6),(2,6),(3,2),(4,2),(2,6),(3,3),(4,3),(2,6),(4,2),(4,6),(4,6),(3,6),(2,6),(2,6),(2,4),(2,4),(2,6),(3,6),(4,2),(4,2),(4,2),(4,2)]
import Data.List
import Data.List.Split
import Data.Ord
import Data.Function(on)

board = [2,3,4,7,1,
         1,5,2,6,2,
         4,3,4,2,1,
         2,1,2,4,1,
         3,1,3,4,1,
         2,1,4,3,2,
         6,9,1,6,4]

n = 5
m = 7

updateBoard board pt =
  let x = fst pt
      y = snd pt
      precedingLines = replicate ((y-2) * n) 0
      bomb = concat $ replicate (if y == 1
                                    then 2
                                    else min 3 (m+2-y)) (replicate (x-2) 0
                                                         ++ (if x == 1
                                                                then [1,1]
                                                                else replicate (min 3 (n+2-x)) 1)
                                                                ++ replicate (n-(x+1)) 0)
  in zipWith (\a b -> max 0 (a-b)) board (precedingLines ++ bomb ++ repeat 0)

showBoard board =
  let top = "   " ++ (concat $ map (\x -> show x ++ ".") [1..n]) ++ "\n"
      chunks = chunksOf n board
  in putStrLn (top ++ showBoard' chunks "" 1)
       where showBoard' []     str count = str
             showBoard' (x:xs) str count =
               showBoard' xs (str ++ show count ++ "." ++ show x ++ "\n") (count+1)

instances _ [] = 0
instances x (y:ys)
  | x == y    = 1 + instances x ys
  | otherwise = instances x ys

density a =
  let numZeros = instances 0 a
      groupsOfZeros = filter (\x -> head x == 0) (group a)
  in if null groupsOfZeros then 0 else numZeros / fromIntegral (length groupsOfZeros)

boardDensity board = sum (map density (chunksOf n board))

moves = [(a,b) | a <- [2..n-1], b <- [2..m-1]]

bestMove board =
  let lowestSumMoves = take 1 $ groupBy ((==) `on` snd)
                              $ sortBy (comparing snd) (map (\x -> (x, sum $ updateBoard board x)) (moves))
  in if null lowestSumMoves
        then (0,0)
        else let lowestSumMoves' = map (\x -> fst x) (head lowestSumMoves)
             in fst $ head $ reverse $ sortBy (comparing snd)
                (map (\x -> (x, boardDensity $ updateBoard board x)) (lowestSumMoves'))

solve board = solve' board [] where
  solve' board result
    | sum board == 0 = result
    | otherwise      =
        let best = bestMove board
        in solve' (updateBoard board best) (result ++ [best])

main :: IO ()
main = mainLoop board where
  mainLoop board = do
    putStrLn ""
    showBoard board
    putStr "Pt: "
    a <- getLine
    case a of
      "quit"    -> do putStrLn ""
                      return ()
      "best"    -> do putStrLn (show $ bestMove board)
                      mainLoop board
      otherwise -> let ws = splitOn "," a
                       pt = (read (head ws), read (last ws))
                   in do mainLoop (updateBoard board pt)

A: You could use state space planning.
For example, using A* (or one of its variants) coupled with an heuristic f = g + h like this:

*

*g: number of bombs dropped so far

*h: sum over all values of the grid divided by 9 (which is the best result, meaning we have an admissible heuristics)

A: There seems to be a nonbipartite matching substructure here.  Consider the following instance:
0010000
1000100
0000001
1000000
0000001
1000100
0010000

The optimal solution to this case has size 5 since that's the size of a minimum cover of the vertices of a 9-cycle by its edges.
This case, in particular, shows that the linear programming relaxation a few people have posted isn't exact, doesn't work, and all those other bad things.  I'm pretty sure I can reduce "cover the vertices of my planar cubic graph by as few edges as possible" to your problem, which makes me doubt whether any of the greedy/hill-climbing solutions are going to work.
I don't see a way to solve this in polynomial time in the worst case.  There might be a very clever binary-search-and-DP solution that I'm not seeing.
EDIT:  I see that the contest (http://deadline24.pl) is language-agnostic; they send you a bunch of input files and you send them outputs.  So you don't need something that runs in worst-case polynomial time.  In particular, you get to look at the input!
There are a bunch of small cases in the input.  Then there's a 10x1000 case, a 100x100 case, and a 1000x1000 case.  The three large cases are all very well-behaved.  Horizontally adjacent entries typically have the same value.  On a relatively beefy machine, I'm able to solve all of the cases by brute-forcing using CPLEX in just a couple of minutes.  I got lucky on the 1000x1000; the LP relaxation happens to have an integral optimal solution.  My solutions agree with the .ans files provided in the test data bundle.
I'd bet you can use the structure of the input in a much more direct way than I did if you took a look at it; seems like you can just pare off the first row, or two, or three repeatedly until you've got nothing left.  (Looks like, in the 1000x1000, all of the rows are nonincreasing?  I guess that's where your "part B" comes from?  )

A: This can be solved using a tree of depth O(3^(n)). Where n is the sum of all of the squares.
First consider that it is trivial to solve the problem with a tree of O(9^n), simply consider all of the possible bombing locations.  For an example see Alfe's implementation.
Next realize that we can work to bomb from the bottom up and still get a minimum bombing pattern.

*

*Start from the bottom left corner.

*Bomb it to oblivion with the only plays that make sense (up and to the right).

*Move one square to the right.

*While the target has a value greater than zero, consider each of the 2 plays that make sense (straight up or up and to the right), reduce the value of the target by one, and make a new branch for each possibility.

*Move another to the right.

*While the target has a value greater than zero, consider each of the 3 plays that make sense (up left, up, and up right), reduce the value of the target by one, and make a new branch for each possibility.

*Repeat steps 5 and 6 until the row is eliminated.

*Move up a row and repeat steps 1 to 7 until the puzzle is solved.

This algorithm is correct because

*

*It is necessary to complete each row at some point.

*Completing a row always requires a play either one above, one below, or within that row.

*It is always as good or better to choose a play one above the lowest uncleared row than a play on the row or below the row.

In practice this algorithm will regularly do better than its theoretical maximum because it will regularly bomb out neighbors and reduce the size of the search.  If we assume that each bombing decreases the value of 4 additional targets, then our algorithm will run in O(3^(n/4)) or approximately O(1.3^n).
Because this algorithm is still exponential, it would be wise to limit the depth of the search.  We might limit the number of branches allowed to some number, X, and once we are this deep we force the algorithm to choose the best path it has identified so far (the one that has the minimum total board sum in one of its terminal leaves).  Then our algorithm is guaranteed to run in O(3^X) time, but it is not guaranteed to get the correct answer.  However, we can always increase X and test empirically if the trade off between increased computation and better answers is worthwhile.

A: I can't think of a way to calculate the actual number without just computing the bombing campaign using my best heuristic and hope I get a reasonable result.
So my method is to compute a bombing efficiency metric for each cell, bomb the cell with the highest value, .... iterate the process until I've flattened everything. Some have advocated using simple potential damage (i.e. score from 0 to 9) as a metric, but that falls short by pounding high value cells and not making use of damage overlap. I'd calculate cell value - sum of all neighbouring cells, reset any positive to 0 and use the absolute value of anything negative. Intuitively this metric should make a selection that help maximise damage overlap on cells with high counts instead of pounding those directly.
The code below reaches total destruction of the test field in 28 bombs (note that using potential damage as metric yields 31!).
using System;
using System.Collections.Generic;
using System.Linq;

namespace StackOverflow
{
  internal class Program
  {
    // store the battle field as flat array + dimensions
    private static int _width = 5;
    private static int _length = 7;
    private static int[] _field = new int[] {
        2, 3, 4, 7, 1,
        1, 5, 2, 6, 2,
        4, 3, 4, 2, 1,
        2, 1, 2, 4, 1,
        3, 1, 3, 4, 1,
        2, 1, 4, 3, 2,
        6, 9, 1, 6, 4
    };
    // this will store the devastation metric
    private static int[] _metric;

    // do the work
    private static void Main(string[] args)
    {
        int count = 0;

        while (_field.Sum() > 0)
        {
            Console.Out.WriteLine("Round {0}:", ++count);
            GetBlastPotential();
            int cell_to_bomb = FindBestBombingSite();
            PrintField(cell_to_bomb);
            Bomb(cell_to_bomb);
        }
        Console.Out.WriteLine("Done in {0} rounds", count);
    }

    // convert 2D position to 1D index
    private static int Get1DCoord(int x, int y)
    {
        if ((x < 0) || (y < 0) || (x >= _width) || (y >= _length)) return -1;
        else
        {
            return (y * _width) + x;
        }
    }

    // Convert 1D index to 2D position
    private static void Get2DCoord(int n, out int x, out int y)
    {
        if ((n < 0) || (n >= _field.Length))
        {
            x = -1;
            y = -1;
        }
        else
        {
            x = n % _width;
            y = n / _width;
        }
    }

    // Compute a list of 1D indices for a cell neighbours
    private static List<int> GetNeighbours(int cell)
    {
        List<int> neighbours = new List<int>();
        int x, y;
        Get2DCoord(cell, out x, out y);
        if ((x >= 0) && (y >= 0))
        {
            List<int> tmp = new List<int>();
            tmp.Add(Get1DCoord(x - 1, y - 1));
            tmp.Add(Get1DCoord(x - 1, y));
            tmp.Add(Get1DCoord(x - 1, y + 1));
            tmp.Add(Get1DCoord(x, y - 1));
            tmp.Add(Get1DCoord(x, y + 1));
            tmp.Add(Get1DCoord(x + 1, y - 1));
            tmp.Add(Get1DCoord(x + 1, y));
            tmp.Add(Get1DCoord(x + 1, y + 1));

            // eliminate invalid coords - i.e. stuff past the edges
            foreach (int c in tmp) if (c >= 0) neighbours.Add(c);
        }
        return neighbours;
    }

    // Compute the devastation metric for each cell
    // Represent the Value of the cell minus the sum of all its neighbours
    private static void GetBlastPotential()
    {
        _metric = new int[_field.Length];
        for (int i = 0; i < _field.Length; i++)
        {
            _metric[i] = _field[i];
            List<int> neighbours = GetNeighbours(i);
            if (neighbours != null)
            {
                foreach (int j in neighbours) _metric[i] -= _field[j];
            }
        }
        for (int i = 0; i < _metric.Length; i++)
        {
            _metric[i] = (_metric[i] < 0) ? Math.Abs(_metric[i]) : 0;
        }
    }

    //// Compute the simple expected damage a bomb would score
    //private static void GetBlastPotential()
    //{
    //    _metric = new int[_field.Length];
    //    for (int i = 0; i < _field.Length; i++)
    //    {
    //        _metric[i] = (_field[i] > 0) ? 1 : 0;
    //        List<int> neighbours = GetNeighbours(i);
    //        if (neighbours != null)
    //        {
    //            foreach (int j in neighbours) _metric[i] += (_field[j] > 0) ? 1 : 0;
    //        }
    //    }
    //}

    // Update the battle field upon dropping a bomb
    private static void Bomb(int cell)
    {
        List<int> neighbours = GetNeighbours(cell);
        foreach (int i in neighbours)
        {
            if (_field[i] > 0) _field[i]--;
        }
    }

    // Find the best bombing site - just return index of local maxima
    private static int FindBestBombingSite()
    {
        int max_idx = 0;
        int max_val = int.MinValue;
        for (int i = 0; i < _metric.Length; i++)
        {
            if (_metric[i] > max_val)
            {
                max_val = _metric[i];
                max_idx = i;
            }
        }
        return max_idx;
    }

    // Display the battle field on the console
    private static void PrintField(int cell)
    {
        for (int x = 0; x < _width; x++)
        {
            for (int y = 0; y < _length; y++)
            {
                int c = Get1DCoord(x, y);
                if (c == cell)
                    Console.Out.Write(string.Format("[{0}]", _field[c]).PadLeft(4));
                else
                    Console.Out.Write(string.Format(" {0} ", _field[c]).PadLeft(4));
            }
            Console.Out.Write(" || ");
            for (int y = 0; y < _length; y++)
            {
                int c = Get1DCoord(x, y);
                if (c == cell)
                    Console.Out.Write(string.Format("[{0}]", _metric[c]).PadLeft(4));
                else
                    Console.Out.Write(string.Format(" {0} ", _metric[c]).PadLeft(4));
            }
            Console.Out.WriteLine();
        }
        Console.Out.WriteLine();
    }
  }
}

The resulting bombing pattern is output as follows (field values on the left, metric on the right)
Round 1:
  2   1   4   2   3   2   6  ||   7  16   8  10   4  18   6
  3   5   3   1   1   1   9  ||  11  18  18  21  17  28   5
  4  [2]  4   2   3   4   1  ||  19 [32] 21  20  17  24  22
  7   6   2   4   4   3   6  ||   8  17  20  14  16  22   8
  1   2   1   1   1   2   4  ||  14  15  14  11  13  16   7

Round 2:
  2   1   4   2   3   2   6  ||   5  13   6   9   4  18   6
  2   4   2   1   1  [1]  9  ||  10  15  17  19  17 [28]  5
  3   2   3   2   3   4   1  ||  16  24  18  17  17  24  22
  6   5   1   4   4   3   6  ||   7  14  19  12  16  22   8
  1   2   1   1   1   2   4  ||  12  12  12  10  13  16   7

Round 3:
  2   1   4   2   2   1   5  ||   5  13   6   7   3  15   5
  2   4   2   1   0   1   8  ||  10  15  17  16  14  20   2
  3  [2]  3   2   2   3   0  ||  16 [24] 18  15  16  21  21
  6   5   1   4   4   3   6  ||   7  14  19  11  14  19   6
  1   2   1   1   1   2   4  ||  12  12  12  10  13  16   7

Round 4:
  2   1   4   2   2   1   5  ||   3  10   4   6   3  15   5
  1   3   1   1   0   1   8  ||   9  12  16  14  14  20   2
  2   2   2   2   2  [3]  0  ||  13  16  15  12  16 [21] 21
  5   4   0   4   4   3   6  ||   6  11  18   9  14  19   6
  1   2   1   1   1   2   4  ||  10   9  10   9  13  16   7

Round 5:
  2   1   4   2   2   1   5  ||   3  10   4   6   2  13   3
  1   3   1   1   0  [0]  7  ||   9  12  16  13  12 [19]  2
  2   2   2   2   1   3   0  ||  13  16  15  10  14  15  17
  5   4   0   4   3   2   5  ||   6  11  18   7  13  17   6
  1   2   1   1   1   2   4  ||  10   9  10   8  11  13   5

Round 6:
  2   1   4   2   1   0   4  ||   3  10   4   5   2  11   2
  1   3   1   1   0   0   6  ||   9  12  16  11   8  13   0
  2   2   2   2   0   2   0  ||  13  16  15   9  14  14  15
  5   4  [0]  4   3   2   5  ||   6  11 [18]  6  11  15   5
  1   2   1   1   1   2   4  ||  10   9  10   8  11  13   5

Round 7:
  2   1   4   2   1   0   4  ||   3  10   4   5   2  11   2
  1   3   1   1   0   0   6  ||   8  10  13   9   7  13   0
  2  [1]  1   1   0   2   0  ||  11 [15] 12   8  12  14  15
  5   3   0   3   3   2   5  ||   3   8  10   3   8  15   5
  1   1   0   0   1   2   4  ||   8   8   7   7   9  13   5

Round 8:
  2   1   4   2   1   0   4  ||   1   7   2   4   2  11   2
  0   2   0   1   0   0   6  ||   7   7  12   7   7  13   0
  1   1   0   1   0   2   0  ||   8   8  10   6  12  14  15
  4   2   0   3   3  [2]  5  ||   2   6   8   2   8 [15]  5
  1   1   0   0   1   2   4  ||   6   6   6   7   9  13   5

Round 9:
  2   1   4   2   1   0   4  ||   1   7   2   4   2  11   2
  0   2   0   1   0   0   6  ||   7   7  12   7   6  12   0
  1   1   0   1   0  [1]  0  ||   8   8  10   5  10 [13] 13
  4   2   0   3   2   2   4  ||   2   6   8   0   6   9   3
  1   1   0   0   0   1   3  ||   6   6   6   5   8  10   4

Round 10:
  2   1   4   2   1   0   4  ||   1   7   2   4   2  10   1
  0   2  [0]  1   0   0   5  ||   7   7 [12]  7   6  11   0
  1   1   0   1   0   1   0  ||   8   8  10   4   8   9  10
  4   2   0   3   1   1   3  ||   2   6   8   0   6   8   3
  1   1   0   0   0   1   3  ||   6   6   6   4   6   7   2

Round 11:
  2   0   3   1   1   0   4  ||   0   6   0   3   0  10   1
  0   1   0   0   0  [0]  5  ||   4   5   5   5   3 [11]  0
  1   0   0   0   0   1   0  ||   6   8   6   4   6   9  10
  4   2   0   3   1   1   3  ||   1   5   6   0   5   8   3
  1   1   0   0   0   1   3  ||   6   6   6   4   6   7   2

Round 12:
  2   0   3   1   0   0   3  ||   0   6   0   2   1   7   1
  0   1   0   0   0   0   4  ||   4   5   5   4   1   7   0
  1   0   0   0   0  [0]  0  ||   6   8   6   4   5  [9]  8
  4   2   0   3   1   1   3  ||   1   5   6   0   4   7   2
  1   1   0   0   0   1   3  ||   6   6   6   4   6   7   2

Round 13:
  2   0   3   1   0   0   3  ||   0   6   0   2   1   6   0
  0   1   0   0   0   0   3  ||   4   5   5   4   1   6   0
  1  [0]  0   0   0   0   0  ||   6  [8]  6   3   3   5   5
  4   2   0   3   0   0   2  ||   1   5   6   0   4   6   2
  1   1   0   0   0   1   3  ||   6   6   6   3   4   4   0

Round 14:
  2   0   3   1   0  [0]  3  ||   0   5   0   2   1  [6]  0
  0   0   0   0   0   0   3  ||   2   5   4   4   1   6   0
  0   0   0   0   0   0   0  ||   4   4   4   3   3   5   5
  3   1   0   3   0   0   2  ||   0   4   5   0   4   6   2
  1   1   0   0   0   1   3  ||   4   4   5   3   4   4   0

Round 15:
  2   0   3   1   0   0   2  ||   0   5   0   2   1   4   0
  0   0   0   0   0   0   2  ||   2   5   4   4   1   4   0
  0   0   0   0   0   0   0  ||   4   4   4   3   3   4   4
  3   1   0   3   0  [0]  2  ||   0   4   5   0   4  [6]  2
  1   1   0   0   0   1   3  ||   4   4   5   3   4   4   0

Round 16:
  2  [0]  3   1   0   0   2  ||   0  [5]  0   2   1   4   0
  0   0   0   0   0   0   2  ||   2   5   4   4   1   4   0
  0   0   0   0   0   0   0  ||   4   4   4   3   3   3   3
  3   1   0   3   0   0   1  ||   0   4   5   0   3   3   1
  1   1   0   0   0   0   2  ||   4   4   5   3   3   3   0

Round 17:
  1   0   2   1   0   0   2  ||   0   3   0   1   1   4   0
  0   0   0   0   0   0   2  ||   1   3   3   3   1   4   0
  0   0   0   0   0   0   0  ||   4   4   4   3   3   3   3
  3   1  [0]  3   0   0   1  ||   0   4  [5]  0   3   3   1
  1   1   0   0   0   0   2  ||   4   4   5   3   3   3   0

Round 18:
  1   0   2   1   0   0   2  ||   0   3   0   1   1   4   0
  0   0   0   0   0   0   2  ||   1   3   3   3   1   4   0
  0   0   0   0   0   0   0  ||   3   3   2   2   2   3   3
  3  [0]  0   2   0   0   1  ||   0  [4]  2   0   2   3   1
  1   0   0   0   0   0   2  ||   2   4   2   2   2   3   0

Round 19:
  1   0   2   1   0  [0]  2  ||   0   3   0   1   1  [4]  0
  0   0   0   0   0   0   2  ||   1   3   3   3   1   4   0
  0   0   0   0   0   0   0  ||   2   2   2   2   2   3   3
  2   0   0   2   0   0   1  ||   0   2   2   0   2   3   1
  0   0   0   0   0   0   2  ||   2   2   2   2   2   3   0

Round 20:
  1  [0]  2   1   0   0   1  ||   0  [3]  0   1   1   2   0
  0   0   0   0   0   0   1  ||   1   3   3   3   1   2   0
  0   0   0   0   0   0   0  ||   2   2   2   2   2   2   2
  2   0   0   2   0   0   1  ||   0   2   2   0   2   3   1
  0   0   0   0   0   0   2  ||   2   2   2   2   2   3   0

Round 21:
  0   0   1   1   0   0   1  ||   0   1   0   0   1   2   0
  0   0   0   0   0   0   1  ||   0   1   2   2   1   2   0
  0   0   0   0   0   0   0  ||   2   2   2   2   2   2   2
  2   0   0   2   0  [0]  1  ||   0   2   2   0   2  [3]  1
  0   0   0   0   0   0   2  ||   2   2   2   2   2   3   0

Round 22:
  0   0   1   1   0   0   1  ||   0   1   0   0   1   2   0
  0   0   0   0   0   0   1  ||   0   1   2   2   1   2   0
 [0]  0   0   0   0   0   0  ||  [2]  2   2   2   2   1   1
  2   0   0   2   0   0   0  ||   0   2   2   0   2   1   1
  0   0   0   0   0   0   1  ||   2   2   2   2   2   1   0

Round 23:
  0   0   1   1   0   0   1  ||   0   1   0   0   1   2   0
  0   0  [0]  0   0   0   1  ||   0   1  [2]  2   1   2   0
  0   0   0   0   0   0   0  ||   1   1   2   2   2   1   1
  1   0   0   2   0   0   0  ||   0   1   2   0   2   1   1
  0   0   0   0   0   0   1  ||   1   1   2   2   2   1   0

Round 24:
  0   0   0   0   0   0   1  ||   0   0   0   0   0   2   0
  0   0   0   0   0   0   1  ||   0   0   0   0   0   2   0
  0   0  [0]  0   0   0   0  ||   1   1  [2]  2   2   1   1
  1   0   0   2   0   0   0  ||   0   1   2   0   2   1   1
  0   0   0   0   0   0   1  ||   1   1   2   2   2   1   0

Round 25:
  0   0   0   0   0  [0]  1  ||   0   0   0   0   0  [2]  0
  0   0   0   0   0   0   1  ||   0   0   0   0   0   2   0
  0   0   0   0   0   0   0  ||   1   1   1   1   1   1   1
  1   0   0   1   0   0   0  ||   0   1   1   0   1   1   1
  0   0   0   0   0   0   1  ||   1   1   1   1   1   1   0

Round 26:
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
 [0]  0   0   0   0   0   0  ||  [1]  1   1   1   1   0   0
  1   0   0   1   0   0   0  ||   0   1   1   0   1   1   1
  0   0   0   0   0   0   1  ||   1   1   1   1   1   1   0

Round 27:
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0  [0]  0   0   0   0  ||   0   0  [1]  1   1   0   0
  0   0   0   1   0   0   0  ||   0   0   1   0   1   1   1
  0   0   0   0   0   0   1  ||   0   0   1   1   1   1   0

Round 28:
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0   0   0   0   0   0  ||   0   0   0   0   0   0   0
  0   0   0   0   0  [0]  0  ||   0   0   0   0   0  [1]  1
  0   0   0   0   0   0   1  ||   0   0   0   0   0   1   0

Done in 28 rounds

A: evaluation function, total sum:
int f (int ** matrix, int width, int height, int x, int y)
{
    int m[3][3] = { 0 };

    m[1][1] = matrix[x][y];
    if (x > 0) m[0][1] = matrix[x-1][y];
    if (x < width-1) m[2][1] = matrix[x+1][y];

    if (y > 0)
    {
        m[1][0] = matrix[x][y-1];
        if (x > 0) m[0][0] = matrix[x-1][y-1];
        if (x < width-1) m[2][0] = matrix[x+1][y-1];
    }

    if (y < height-1)
    {
        m[1][2] = matrix[x][y+1];
        if (x > 0) m[0][2] = matrix[x-1][y+1];
        if (x < width-1) m[2][2] = matrix[x+1][y+1];
    }

    return m[0][0]+m[0][1]+m[0][2]+m[1][0]+m[1][1]+m[1][2]+m[2][0]+m[2][1]+m[2][2];
}

objective function:
Point bestState (int ** matrix, int width, int height)
{
    Point p = new Point(0,0);
    int bestScore = 0;
    int b = 0;

    for (int i=0; i<width; i++)
        for (int j=0; j<height; j++)
        {
            b = f(matrix,width,height,i,j);

            if (b > bestScore)
            {
                bestScore = best;
                p = new Point(i,j);
            }
        }

    retunr p;
}

destroy function:
void destroy (int ** matrix, int width, int height, Point p)
{
    int x = p.x;
    int y = p.y;

    if(matrix[x][y] > 0) matrix[x][y]--;
    if (x > 0) if(matrix[x-1][y] > 0) matrix[x-1][y]--;
    if (x < width-1) if(matrix[x+1][y] > 0) matrix[x+1][y]--;

    if (y > 0)
    {
        if(matrix[x][y-1] > 0) matrix[x][y-1]--;
        if (x > 0) if(matrix[x-1][y-1] > 0) matrix[x-1][y-1]--;
        if (x < width-1) if(matrix[x+1][y-1] > 0) matrix[x+1][y-1]--;
    }

    if (y < height-1)
    {
        if(matrix[x][y] > 0) matrix[x][y+1]--;
        if (x > 0) if(matrix[x-1][y+1] > 0) matrix[x-1][y+1]--;
        if (x < width-1) if(matrix[x+1][y+1] > 0) matrix[x+1][y+1]--;
    }
}

goal function:
bool isGoal (int ** matrix, int width, int height)
{
    for (int i=0; i<width; i++)
        for (int j=0; j<height; j++)
            if (matrix[i][j] > 0)
                return false;
    return true;
}

linear maximization function:
void solve (int ** matrix, int width, int height)
{
    while (!isGoal(matrix,width,height))
    {
        destroy(matrix,width,height, bestState(matrix,width,height));
    }
}

This is not optimal, but can be optimized through finding a better evaluation function ..
.. but thinking about this problem, I was thinking that one of the main issues is getting abandoned figures in the middle of zeroes at some point, so I'd take another approach .. which is dominate minimal values into zero, then try to escape zeroes as possible, which lead to general minimization of minimal existing value(s) or so

A: This was an answer to the first asked question. I hadn't noticed that he changed the parameters.
Create a list of all targets. Assign a value to the target based on the number of positive values impacted by a drop (itself, and all neighbors). Highest value would be a nine.
Sort the targets by the number of targets impacted (Descending), with a secondary descending sort on the sum of each impacted target.
Drop a bomb on the highest ranked target, then re-calculate targets and repeat until all target values are zero.
Agreed, this is not always the most optimal. For example,
100011
011100
011100
011100
000000
100011

This approach would take 5 bombs to clear. Optimally, though, you could do it in 4. Still, pretty
darn close and there is no backtracking. For most situations it will be optimal, or very close.
Using the original problem numbers, this approach solves in 28 bombs.
Adding code to demonstrate this approach (using a form with a button):
         private void button1_Click(object sender, EventArgs e)
    {
        int[,] matrix = new int[10, 10] {{5, 20, 7, 1, 9, 8, 19, 16, 11, 3},
                                         {17, 8, 15, 17, 12, 4, 5, 16, 8, 18},
                                         { 4, 19, 12, 11, 9, 7, 4, 15, 14, 6},
                                         { 17, 20, 4, 9, 19, 8, 17, 2, 10, 8},
                                         { 3, 9, 10, 13, 8, 9, 12, 12, 6, 18},
                                         {16, 16, 2, 10, 7, 12, 17, 11, 4, 15},
                                         { 11, 1, 15, 1, 5, 11, 3, 12, 8, 3},
                                         { 7, 11, 16, 19, 17, 11, 20, 2, 5, 19},
                                         { 5, 18, 2, 17, 7, 14, 19, 11, 1, 6},
                                         { 13, 20, 8, 4, 15, 10, 19, 5, 11, 12}};

        int value = 0;
        List<Target> Targets = GetTargets(matrix);
        while (Targets.Count > 0)
        {
            BombTarget(ref matrix, Targets[0]);
            value += 1;
            Targets = GetTargets(matrix);
        }
        Console.WriteLine( value);
        MessageBox.Show("done: " + value);
    }

    private static void BombTarget(ref int[,] matrix, Target t)
    {
        for (int a = t.x - 1; a <= t.x + 1; a++)
        {
            for (int b = t.y - 1; b <= t.y + 1; b++)
            {
                if (a >= 0 && a <= matrix.GetUpperBound(0))
                {
                    if (b >= 0 && b <= matrix.GetUpperBound(1))
                    {
                        if (matrix[a, b] > 0)
                        {
                            matrix[a, b] -= 1;
                        }
                    }
                }
            }
        }
        Console.WriteLine("Dropped bomb on " + t.x + "," + t.y);
    }

    private static List<Target> GetTargets(int[,] matrix)
    {
        List<Target> Targets = new List<Target>();
        int width = matrix.GetUpperBound(0);
        int height = matrix.GetUpperBound(1);
        for (int x = 0; x <= width; x++)
        {
            for (int y = 0; y <= height; y++)
            {
                Target t = new Target();
                t.x = x;
                t.y = y;
                SetTargetValue(matrix, ref t);
                if (t.value > 0) Targets.Add(t);
            }
        }
        Targets = Targets.OrderByDescending(x => x.value).ThenByDescending( x => x.sum).ToList();
        return Targets;
    }

    private static void SetTargetValue(int[,] matrix, ref Target t)
    {
        for (int a = t.x - 1; a <= t.x + 1; a++)
        {
            for (int b = t.y - 1; b <= t.y + 1; b++)
            {
                if (a >= 0 && a <= matrix.GetUpperBound(0))
                {
                    if (b >= 0 && b <= matrix.GetUpperBound(1))
                    {
                        if (matrix[ a, b] > 0)
                        {
                            t.value += 1;
                            t.sum += matrix[a,b];
                        }

                    }
                }
            }
        }

    }

A class you will need:
        class Target
    {
        public int value;
        public int sum;
        public int x;
        public int y;
    }

A: All this problem boils down to is computing an edit distance.  Simply calculate a variant of the Levenshtein distance between the given matrix and the zero matrix, where edits are replaced with bombings, using dynamic programming to store the distances between intermediate arrays.  I suggest using a hash of the matrices as a key.  In pseudo-Python:
memo = {}

def bomb(matrix,i,j):
    # bomb matrix at i,j

def bombsRequired(matrix,i,j):
    # bombs required to zero matrix[i,j]

def distance(m1, i, len1, m2, j, len2):
    key = hash(m1)
    if memo[key] != None:
        return memo[key]

    if len1 == 0: return len2
    if len2 == 0: return len1

    cost = 0
    if m1 != m2: cost = m1[i,j]
    m = bomb(m1,i,j)
    dist = distance(str1,i+1,len1-1,str2,j+1,len2-1)+cost)
    memo[key] = dist
    return dist

A: The slowest but simplest and error free algorithm is generate and test all valid possibilities. for this case is very simple (because result is independent on the order of bomb placement).

*

*create funct which N times apply bomp

*create loop for all bompb-placement/bomb-count posibilities  (stop when matrix==0)

*remember always the best solution.

*at the end of loop you have the best solution

*

*not only count of bombs, but also their placement

code can look like this:
void copy(int **A,int **B,int m,int n)
    {
    for (int i=0;i<m;i++)
     for (int j=0;i<n;j++)
       A[i][j]=B[i][j];
    }

bool is_zero(int **M,int m,int n)
    {
    for (int i=0;i<m;i++)
     for (int j=0;i<n;j++)
      if (M[i][j]) return 0;
    return 1;
    }

void drop_bomb(int **M,int m,int n,int i,int j,int N)
    {
    int ii,jj;
    ii=i-1; jj=j-1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i-1; jj=j  ; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i-1; jj=j+1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i  ; jj=j-1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i  ; jj=j  ; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i  ; jj=j+1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i+1; jj=j-1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i+1; jj=j  ; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    ii=i+1; jj=j+1; if ((ii>=0)&&(ii<m)&&(jj>=0)&&(jj<n)&&(M[ii][jj])) { M[ii][jj]-=N; if (M[ii][jj]<0) M[ii][jj]=0; }
    }

void solve_problem(int **M,int m,int n)
    {
    int i,j,k,max=0;
    // you probably will need to allocate matrices P,TP,TM yourself instead of this:
    int P[m][n],min;             // solution: placement,min bomb count
    int TM[m][n],TP[m][n],cnt;   // temp
    for (i=0;i<m;i++)            // max count of bomb necessary to test
     for (j=0;j<n;j++)
      if (max<M[i][j]) max=M[i][j];
    for (i=0;i<m;i++)            // reset solution
     for (j=0;j<n;j++)
      P[i][j]=max;
    min=m*n*max;
        copy(TP,P,m,n); cnt=min;

    for (;;)  // generate all possibilities
        {
        copy(TM,M,m,n);
        for (i=0;i<m;i++)   // test solution
         for (j=0;j<n;j++)
          drop_bomb(TM,m,n,TP[i][j]);
        if (is_zero(TM,m,n))// is solution
         if (min>cnt)       // is better solution -> store it
            {
            copy(P,TP,m,n);
            min=cnt;
            }
        // go to next possibility
        for (i=0,j=0;;)
            {
            TP[i][j]--;
            if (TP[i][j]>=0) break;
            TP[i][j]=max;
                 i++; if (i<m) break;
            i=0; j++; if (j<n) break;
            break;
            }
        if (is_zero(TP,m,n)) break;
        }
    //result is in P,min
    }

this can be optimized in lot of ways,... simplest is to reset solution with M matrix, but you need change the max value and also the TP[][] decrement code

A: Several answers so far give exponential time, some involve dynamic programming. I doubt if those are necessary.
My solution is O(mnS) where m, n are dimensions of the board, S is the sum of all integers. The idea is rather bruteforce: find the location that can kill the most each time and terminate at 0.
It gives 28 moves for the board given, and also prints out the board after each drop.
Complete, self-explanatory code:
import java.util.Arrays;

public class BombMinDrops {

    private static final int[][] BOARD = {{2,3,4,7,1}, {1,5,2,6,2}, {4,3,4,2,1}, {2,1,2,4,1}, {3,1,3,4,1}, {2,1,4,3,2}, {6,9,1,6,4}};
    private static final int ROWS = BOARD.length;
    private static final int COLS = BOARD[0].length;
    private static int remaining = 0;
    private static int dropCount = 0;
    static {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                remaining = remaining + BOARD[i][j];
            }
        }
    }

    private static class Point {
        int x, y;
        int kills;

        Point(int x, int y, int kills) {
            this.x = x;
            this.y = y;
            this.kills = kills;
        }

        @Override
        public String toString() {
            return dropCount + "th drop at [" + x + ", " + y + "] , killed " + kills;
        }
    }

    private static int countPossibleKills(int x, int y) {
        int count = 0;
        for (int row = x - 1; row <= x + 1; row++) {
            for (int col = y - 1; col <= y + 1; col++) {
                try {
                    if (BOARD[row][col] > 0) count++;
                } catch (ArrayIndexOutOfBoundsException ex) {/*ignore*/}
            }
        }

        return count;
    }

    private static void drop(Point here) {
        for (int row = here.x - 1; row <= here.x + 1; row++) {
            for (int col = here.y - 1; col <= here.y + 1; col++) {
                try {
                    if (BOARD[row][col] > 0) BOARD[row][col]--;
                } catch (ArrayIndexOutOfBoundsException ex) {/*ignore*/}
            }
        }

        dropCount++;
        remaining = remaining - here.kills;
        print(here);
    }

    public static void solve() {
        while (remaining > 0) {
            Point dropWithMaxKills = new Point(-1, -1, -1);
            for (int i = 0; i < ROWS; i++) {
                for (int j = 0; j < COLS; j++) {
                    int possibleKills = countPossibleKills(i, j);
                    if (possibleKills > dropWithMaxKills.kills) {
                        dropWithMaxKills = new Point(i, j, possibleKills);
                    }
                }
            }

            drop(dropWithMaxKills);
        }

        System.out.println("Total dropped: " + dropCount);
    }

    private static void print(Point drop) {
        System.out.println(drop.toString());
        for (int[] row : BOARD) {
            System.out.println(Arrays.toString(row));
        }

        System.out.println();
    }

    public static void main(String[] args) {
        solve();
    }

}


text:
Q: Calculate mm:ss + mm:ss I'm looking for js that does something similar to this: http://www.unitarium.com/time-calculator.
My song-lengths are in an array, not in form fields. And the result have to display hh:mm:ss when needed (or always).
This is the page I want to use this on: http://flamencopeko.net/songs.php.

A: Make a function to convert the format mm:ss to seconds, and one to convert seconds to the format hh:mm:ss, convert all values to seconds, add them together, and format the result:
function parseMS(s) {
    var parts = s.split(':');
    return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
}

function formatTwo(n) {
    return (n < 10 ? '0' : '') + n.toString();
}

function formatHMS(s) {
    var m = Math.floor(s / 60);
    s %= 60;
    var h = Math.floor(m / 60);
    m %= 60;
    return formatTwo(h) + ':' + formatTwo(m) + ':' + formatTwo(s);
}

var times = ['14:23', '11:08', '18:59'];

var sum = 0;
for (var i = 0; i < times.length; i++) sum += parseMS(times[i]);
var result = formatHMS(sum);

alert(result);

Demo: http://jsfiddle.net/u6B4g/

A: I was able to use this PHP:
$str_time = "2:50";

sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);

$time_seconds = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes;

from Convert time in HH:MM:SS format to seconds only? to make bars for my song-lengths here: http://flamencopeko.net/songs.php.
I'll try to use that to get total playing time now.
I think array_sum() is the way to go, but I don't know how.
Up to date source: http://flamencopeko.net/covers.txt.

redpajama_set_name: RedPajamaStackExchange


text:
Q: Memory efficient way to manipulate images? I have some code that takes two images and merges the middle section of them together into one image. The code works, but uses quite a lot of memory, so it fails on some devices that don't have enough memory.
Is there some way to make this code more memory efficient?
The code
private void convertImages(){
    ImageView imageView = (ImageView) findViewById(R.id.imageView);

    File leftFile = new File(Environment.getExternalStorageDirectory(), "images/left.jpg");
    File rightFile = new File(Environment.getExternalStorageDirectory(), "images/right.jpg");

    Bitmap left = BitmapFactory.decodeFile(leftFile.getAbsolutePath());
    Bitmap right = BitmapFactory.decodeFile(rightFile.getAbsolutePath());

    Rect srcRect = new Rect( (int)(left.getWidth()*0.25), 0, (int)(left.getWidth()*0.75), left.getHeight() );
    Rect dstRectLeft = new Rect( 0, 0, (int)(srcRect.width()/2), srcRect.height() );
    Rect dstRectRight = new Rect( (int)(srcRect.width()/2), 0, srcRect.width(), srcRect.height() );

    Bitmap outBitmap = Bitmap.createBitmap(srcRect.width(), srcRect.height(), Bitmap.Config.ARGB_8888);
    Canvas outCanvas = new Canvas(outBitmap);
    outCanvas.drawBitmap(left, srcRect, dstRectLeft, null);
    outCanvas.drawBitmap(right, srcRect, dstRectRight, null);

    imageView.setImageBitmap( outBitmap );
}

A: You can try compression. Try this helpful imagecompressor class, copied and pasted for your convenience into this thread:
Android: Compressing images creates black borders on left and top margin
The compressor java will compress your pictures to about 1/10 of their size so for a 3mb picture, it will become 300kb. Hopefully that will save you some memory.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import timber.log.Timber;

//http://voidcanvas.com/whatsapp-like-image-compression-in-android/
public class ImageCompressor {

    public ImageCompressor() {}

    public static String compressImage(String imagePath, Context context) {
        Bitmap scaledBitmap = null;
        String filename = "compressed_" +imagePath.substring(imagePath.lastIndexOf("/")+1);

        BitmapFactory.Options options = new BitmapFactory.Options();

//      by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
//      you try the use the bitmap here, you will get null.
        options.inJustDecodeBounds = true;
        Timber.e( "imagePath "+imagePath);
        Timber.e("filename "+filename);
        Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
        if (options == null) {
            Timber.e("zero bitmap");
        }
        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;
        float imgRatio = actualWidth / actualHeight;

        float maxHeight = actualHeight * 10/20;
        float maxWidth = actualWidth * 10/20;
        float maxRatio = maxWidth / maxHeight;

//      width and height values are set maintaining the aspect ratio of the image

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {

                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;

            } else if (imgRatio > maxRatio) {

                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;

            } else {

                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

//      setting inSampleSize value allows to load a scaled down version of the original image

        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);

//      inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;

//      this options allow android to claim the bitmap memory if it runs low on memory
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
//          load the bitmap from its path
            bmp = BitmapFactory.decodeFile(imagePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();

        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

//      check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(imagePath);

            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Timber.e("Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                Timber.e( "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Timber.e( "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Timber.e( "Exif: " + orientation);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                    true);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        FileOutputStream out = null;

        try {

            out = context.openFileOutput(filename, Context.MODE_PRIVATE);
            scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);

            out.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
            return filename;
        }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height/ (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;      }
        final float totalPixels = width * height;
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;
        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }
        return inSampleSize;
    }

}
}

A: You can use the Bitmap.createScaledBitmap(src, dstWidth, dstHeight, filter); method to scale down bitmaps so its size will be much more smaller


text:
Q: Chamilo ERROR : Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /srv/disk8/1265300/www/portal.mdg-5.org/index.php on line 9 I have the following error with my Chamilo

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in
  /srv/disk8/1265300/www/portal.mdg-5.org/index.php on line 9
Parse error: syntax error, unexpected T_STRING, expecting
  T_CONSTANT_ENCAPSED_STRING or '(' in
  /srv/disk8/1265300/www/portal.mdg-5.org/index.php on line 9

On line 9 is the following code:
use \ChamiloSession as Session;

I'm using PHP 5.2.17.

A: This happens because the code you are using is attempting to use PHP namespaces. Namespaces were only introduced in PHP 5.3 and will not work on your system.
PHP >5.3 is specified as a requirement on the Chamilo website.
Unfortunately, there is essentially nothing you can do short of upgrading your version of PHP. If you are on shared hosting, this will of course be rather difficult.


text:
Q: Microsoft Azure,Webjob, in which timezone a webjob runs if I schedule a webjob to run daily at specified time using cron expression I scheduled a webjob to run daily at 2 am using cron expression (0 0 2 * * *) following tutorial from Create a scheduled WebJob using a CRON expression
 and my server is created in "north central US" region, so i hope it should run in US central timezone but seems it running at different time than what i specified.

A: Based on the comments mentioned here, WebJobs run into the timezone configured for the WebApp where your WebJob is hosted. From this post:

Assuming you have not configured anything for the timezone, your cron job should use UTC which is the default timezone in Azure.
From Changing the server time zone on Azure Web Apps, you can specify the time zone you want your application to run in by making an application setting called WEBSITE_TIME_ZONE and set it to a proper value. From this blog post:

If your app is hosted as a Web App on the Azure App Service (formerly
  known as Azure Websites), until recently you were completely out of
  luck. However there is now an easy and supported way to change the
  time zone for your w3wp process (and any processes it spawns):
All you need to do is add an Application Setting (via the portal or
  the management APIs) called WEBSITE_TIME_ZONE and set that to the name
  of the time zone as defined in the Windows Registry under
  HKLM\Software\Microsoft\Windows Nt\CurrentVersion\Time Zones\ (for
  example, "AUS Eastern Standard Time").

A: The default time zone is GMT as per the MS documentation
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp#ncrontab-time-zones


text:
Q: "refer to the Teachers' Lounge" and "your fellow moderators" is inconsistent with reference to site mods vs network mods When preparing to send a moderator message, all moderators see this:

I'm talking about the last line:

If in doubt, please refer to the Teachers' Lounge and ask your fellow moderators.

Now... the TL is for all moderators on the network, some 566 people, plus Stack Overflow Inc. staff members. But that link goes to https://<site>.stackexchange.com/users?tab=moderators, which is a much smaller pool of people... ranging from 2 to 25.
Now, most sites have a per-site mod chatroom for having discussions related to the moderation of their site. That's where you usually go for getting the opinion of your site mods; the TL is for getting the opinion of the network mods.
Go to [place] and do [thing] implies that you'll be doing [thing] in [place]; in this case, that's talking to your fellow site mods in the TL.
I'm assuming that this is actually supposed to mean get the opinions of your local mod team or head to the TL and get the views of the mods around the network, in which case the "and" should probably be changed to "or".
The other interpretation is that the "fellow moderators" link should go /about/moderators, which is actually a list of who you can find in the TL.
In any case, this is slightly confusing and misleading.
1.) What is this actually supposed to mean? "and" or "or"?
2.) Can this please be changed to something less ambiguous?
See also the TL transcript.

A: Site's mod room is not mandatory and the TL is supposed to be a common place to discuss things.
Indeed if there's a long talk about a site specific thing opening a room sounds a good idea to avoid filling the TL for a 2 or 3 person talk.
All in all linking to the TL doesn't really harm and I'm unsure it needs rewording. If it was to be said another way I'm afraid it would turn in a complex and too long sentence or a too large paragraph for the place it is displayed in.
I didn't see it causing problem so I feel it's an over optimisation.

A: There's usually communications methods, both official and unofficial, in addition to TL - for example there's private chat room for mods, or even chatrooms for similar sites to share their experiences.
TL is one of many places where moderators can communicate, and there's certain things that you probably should be talking to site mods, not network mods.
The fact that TL is sometimes a good place to pick on the brains of a small subset of the collective moderator experience, and that mods on other sites sometimes have good insights to share dosen't mean that the primary source of mod-advice is the folks on TL...
So - the and seems appropriate, and refers to site mods to me.
Also, there's only a small subset of mods on anyway? Pretty sure TL hardly hits the hundreds let alone 500+ users at once

A:
Go to [place] and do [thing] implies that you'll be doing [thing] in [place]

I disagree. The context here is "if in doubt, please do X and Y". That doesn't necessarily mean X and Y are part of the same process; they might be (and indeed are) two different things you should try doing.
If, as a moderator, I'm not sure how to handle a flag, my first ports of call to get help will be to ask for advice in TL and to consult the other mods of my site (usually in our private chatroom, possibly by raising a mod flag on-site myself). Notice how I used the word "and" in that sentence? :-)
Also, there's no reason you can't consult your fellow site mods in the TL. They're not mutually exclusive; if it's not a private thing involving PII or a very site-specific issue, you might just as well chat to the other mods from your own site in TL. That way, other sites' mods might be able to chip in if they have useful advice, or learn something if they don't.
TL;DR: I think this is status-bydesign.


text:
Q: Using socat to relay one TTY stream to multiple TCP/IP destinations, plus to one 'sniffer' program Using an embedded Linux development board, I need to put together a widget that does the following:

*

*Reads packets in via physical serial port, and relays those packets to a number of IP addresses (up to 20 of them; with IP destinations read from a configuration file).

*Also 'sniff' those serial packets using a custom program, perhaps written in c.

As someone with a programming background, the most obvious solution (to me) would be to create a c program from scratch to achieve the above. However, as this is something I need to throw together quickly, and because I need an excuse to learn more about existing Linux command-line programs and script writing (which I'm not so good at), I'm wondering if much of this could be achieved with existing command-line programs and a shell script. Then, the only part I write from scratch is my packet sniffer (call it sniffer.c).
I understand that netcat and socat can be used for relaying between devices and addresses, and I have started experimenting with both. The thought occurs to me that I could avoid having to develop and test TCP/IP software by running multiple instances of socat to relay serial data from the TTY port to remote IP addresses. Each instance of socat could handle a particular remote IP address.
Does this sound feasible, and if so, how could I effectively 'multiplex' a stream from /dev/ttyS0 (say) as the source for multiple instances of socat plus one instance of sniffer.c? Could one way be to relay data read from /dev/ttyS0 to a cache file, and then have my socat instances and sniffer.c all have a read-only access to that file?


text:
Q: bgiframe with jQuery UI 1.8.9 Dialog and jQuery 1.5 So I am using jQuery UI's dialog box. But as I have a read there is a common bug within IE6 (which is unfortunate that I have to make sure this works for) where dropdown lists do not pay attention to z-index queues. I have also read that there is a handy plugin out there called bgiframe to take care of my overlay woes. I have found 2 different ways people say to use it, and neither work. I may just be doing something really stupid but I need to get this working.
including jQuery.bgiframe.js Version 2.1.1
Here are the 2 ways I have attempted to use it without working: (I have included all jQuery-UI, jQuery, and bgiframe in the page that I am working on)

*

*The documentation from the actual plugin says do this:
$("#selectDropdownThatNeedsFixing").bgiframe();

This cause a jQuery exception saying saying Object expected.

*The second way that I saw from the following page: http://docs.jquery.com/UI/Dialog/dialog basically you just set bgiframe: true when you initialize the dialog:
$( ".selector" ).dialog({ bgiframe: true });

This does not error out, but the problem still exists within IE6 when I test it out.
Am I missing something? Which way am I supposed to use bgiframe? Any direction would be much appreciated. Thank you for your help!

A: You don't need to use a plugin for this. The problem with IE6 and z-index is, positioned elements in IE6 generate a new stacking context starting with a z-index value of 0. Therefore z-index doesn't work correctly in IE6. The workaround to this issue is to specify a z-index value in the parent selector that is equal to the z-index specified in the child selector.
Check working example at http://jsfiddle.net/ebgnu/2/
Below is the example i did in jsfiddle.
.parent{
    position: relative;
    color:white;
}
.parent#a {
    height: 2em;
    z-index: 1;
}
.parent#a .child{
    position: absolute;
    height: 6em;
    width: 2em;
    z-index: 1;
    background:blue;
}
.parent#b {
    height: 2em;
    background:red;
}

a

b

Look at .parent#a This is the parent of the child selector a that have a z-index of 1. In this example, a will be on top of b. let's say we want to make b on top on a. All we need to do is change values of both the child a and it's parent to z-index: 0. This will send it to the back.

A: I believe that you're supposed to call the bgiframe plugin on the dialog, not the < select >.
The current jQuery UI version doesn't seem to list the bgiframe option for the dialog widget anymore.
The jQuery Exception you're getting seems to indicate, that the element that you're targeting doesn't exist for the selector specified (#selectDropdownThatNeedsFixing).
If the problem persists, try to use the IE Developer Toolbar to find out if the iframe is actually created.