class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int> >& obstacleGrid) {
        // write code here
        if(obstacleGrid.empty() || obstacleGrid[0].empty())
        {
            return 0;
        }
        const int m = obstacleGrid.size();
        const int n = obstacleGrid[0].size();
        // ==================状态定义 dp[i][j]==============================
        vector<vector<int>> dp (m, vector<int>(n,0));
        //=========================初始化===================================
        for(int i = 0;i<m; i++)
        {
            if(obstacleGrid[i][0]==1)  //   第0行中只要前面有障碍,后面都无法到达
            {
                //dp[i][0] = 0;              // 此行可不加 因为 已经被初始化为0了;
                break;                    // 如果[i][0]有障碍,下面的格子也就不用看了全为0;
            }
            else{  // obstacleGrid[i][0]==0
                dp[i][0] = 1;
            }
        }
        for(int i =0;i<n;i++)
        {
            if(obstacleGrid[0][i] == 0) // 如果无障碍
            {
                dp[0][i] = 1;
            }
            else // 有障碍
            {
               // dp[0][i] = 0;
                break;   
            }  // 如果[i][0]有障碍,后面的格子也就不用看了全为0;
        }
        //=====================状态转移(递推方程)==================================
        for(int i = 1;i<m; i++)
        {
            for(int j = 1;j<n;j++)
            {
                if(obstacleGrid[i][j] == 1)  // obstacleGrid[i][j] = 1 时,F(i,j)无法到达
                {
                    dp[i][j] = 0;
                }

                else
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
         return dp[m-1][n-1];
    }
};