1. 程式人生 > >【多次過】【座標型】Lintcode 553. 炸彈襲擊

【多次過】【座標型】Lintcode 553. 炸彈襲擊

給一個二維矩陣, 每一個格子都可能是一堵牆 W, 一個敵人 E 或者空 0 (數字 '0'), 返回你可以用一個炸彈殺死的最大敵人數. 炸彈會殺死所有在同一行和同一列沒有牆阻隔的敵人, 因為牆比較堅固難以摧毀.

樣例

給一個矩陣:

0 E 0 0
E 0 W E
0 E 0 0

返回 3.(在(1, 1)處放炸彈可以殺死 3 個敵人)

注意事項

你只能在空的地方放置炸彈.


解題思路:

每個炸彈可以往四個方向傳播,我們可以分析一個方向,然後舉一反三,即如果在一個空地放一個炸彈,最多向上炸死多少敵人。

確定狀態:

我們假設有敵人或有牆的格子也能放炸彈。

有敵人的格子:格子的敵人被炸死,並繼續向上爆炸

有牆的格子:炸彈不能炸死任何敵人

 

在(1,j)格放一個炸彈,它向上能炸死的敵人數是:

若(i,j)格為空地:(i-1,j)格向上能炸死的敵人數

若(i,j)格為敵人:(i-1,j)格向上能炸死的敵人數 + 1

若(i,j)格為牆:0

子問題:

需要知道(i-1,j)格放一個炸彈向上能炸死的敵人數。

狀態:dp[i][j]表示(i,j)格放一個炸彈向上能炸死的敵人數

狀態方程:

11

初始條件:與第0行的dp值和格子內容相關

dp[0][j] = 0 , 若(0,j)格不是敵人

dp[0][j] = 1 , 若(0,j)格是敵人

四個方向:

上面只說明瞭向上的炸死敵人數,一共四個方向,同理可類似的計算其餘方向,注意計算順序會有改變。

public class Solution {
    /**
     * @param grid: Given a 2D grid, each cell is either 'W', 'E' or '0'
     * @return: an integer, the maximum enemies you can kill using one bomb
     */
    public int maxKilledEnemies(char[][] grid) {
        // write your code here
        if(grid==null || grid.length==0 || grid[0].length==0)
            return 0;
            
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];
        int[][] res = new int[m][n];
        
        //up
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                if(grid[i][j] == 'W')
                    dp[i][j] = 0;
                else{
                    dp[i][j] = 0;
                    if(grid[i][j] == 'E')
                        dp[i][j] = 1;
                    if(i-1 >= 0)
                        dp[i][j] = dp[i-1][j];
                }
                
                res[i][j] += dp[i][j];
            }
        }
        
        //down
        for(int i=m-1; i>=0; i--){
            for(int j=0; j<n; j++){
                if(grid[i][j] == 'W')
                    dp[i][j] = 0;
                else{
                    dp[i][j] = 0;
                    if(grid[i][j] == 'E')
                        dp[i][j] = 1;
                    if(i+1 < m)
                        dp[i][j] = dp[i+1][j];
                }
                
                res[i][j] += dp[i][j];
            }
        }
        
        //left
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                if(grid[i][j] == 'W')
                    dp[i][j] = 0;
                else{
                    dp[i][j] = 0;
                    if(grid[i][j] == 'E')
                        dp[i][j] = 1;
                    if(j-1 >= 0)
                        dp[i][j] = dp[i][j-1];
                }
                
                res[i][j] += dp[i][j];
            }
        }
        
        //right
        for(int i=0; i<m; i++){
            for(int j=n-1; j>=0; j--){
                if(grid[i][j] == 'W')
                    dp[i][j] = 0;
                else{
                    dp[i][j] = 0;
                    if(grid[i][j] == 'E')
                        dp[i][j] = 1;
                    if(j+1 < n)
                        dp[i][j] = dp[i][j+1];
                }
                
                res[i][j] += dp[i][j];
            }
        }
        
        int result = 0;
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                if(grid[i][j] == '0'){
                    if(res[i][j] > result)
                        result = res[i][j];
                }
            }
        }
        
        return result;
    }
}