ACM總結——動態規劃(5)二維DP

DP系列:

https://blog.csdn.net/nameofcsdn/article/details/106417240

 

因爲最近在寫DP總結系列,所以選了一個二維DP的題目,把各種代碼都寫了一遍,並在此進一步探索。

力扣OJ 63. 不同路徑 II (二維DP)https://blog.csdn.net/nameofcsdn/article/details/106537960

這裏面的4個代碼,涉及到遞歸和非遞歸、非遞歸的不同順序、空間壓縮。

第一個問題來了,非遞歸寫法有沒有空間壓縮寫法呢?

以題目中的數據和我的遞歸算法爲例

輸入:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

int dp(vector<vector<int>>& obs,int x,int y)
{
    if(x<0||x>=obs.size()||y<0||y>=obs[0].size()||obs[x][y])return 0;
    if(ans[x][y])return ans[x][y];
    return ans[x][y]=dp(obs,x,y-1)+dp(obs,x-1,y);
}

首先看看遞歸寫法的調用過程:

可以發現,這棵樹其實是一個斜着的矩形,而這個矩形和輸入的矩形obs是對應的。

然後,我們看看dp函數實際被調用的過程:

class Solution {
public:
    vector<vector<int>>ans;
    int dp(vector<vector<int>>& obs,int x,int y)
    {
        cout<<x<<" "<<y<<"    ";
        if(x<0||x>=obs.size()||y<0||y>=obs[0].size()||obs[x][y])return 0;
        if(ans[x][y])return ans[x][y];
        return ans[x][y]=dp(obs,x,y-1)+dp(obs,x-1,y);
    }
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        ans=obstacleGrid;
        for(int i=0;i<ans.size();i++)for(int j=0;j<ans[0].size();j++)ans[i][j]=0;
        ans[0][0]=1;
        return dp(obstacleGrid,obstacleGrid.size()-1,obstacleGrid[0].size()-1);
    }
};

int main()
{
    vector<int>v1;
    v1.push_back(0);
    v1.push_back(0);
    v1.push_back(0);
    vector<vector<int>>obs;
    obs.push_back(v1);
    obs.push_back(v1);
    obs.push_back(v1);
    obs[1][1]=1;
    Solution s;
    cout<<s.uniquePathsWithObstacles(obs);
	return 0;
}

輸出:

2 2    2 1    2 0    2 -1    1 0    1 -1    0 0    1 1    1 2    1 1    0 2    0 1    0 0    -1 1    -1 2    2

把-1去掉,得到:

2 2   2 1   2 0   1 0     0 0   1 1   1 2   1 1   0 2   0 1   0 0

用同樣的方法,如果輸入的是

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

那麼遞歸的實際執行過程就是

2 2    2 1    2 0    2 -1    1 0    1 -1    0 0    1 1    1 0    0 1    0 0    -1 1    1 2    1 1    0 2    0 1    -1 2    6

把-1去掉,得到:

2 2    2 1    2 0      1 0      0 0    1 1    1 0    0 1    0 0     1 2    1 1    0 2    0 1  

不難看出來,這就是DFS

 

總結:

1,遞歸程序都是基於棧的。

2,DFS是基於棧的,BFS是基於隊列的。

3,動態規劃的問題,解空間都可以映射爲樹。

4,動態規劃的遞歸程序,是對解空間的DFS。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章