第一步. 找出dp狀態的定義
第二步. 找到dp遞推方程
Leetcode120. 三角形的最小路徑和 動態規劃 時間複雜度 O(m*k) 空間複雜度 O(m*k)
一種較爲好理解的解法,定義一個二維的數組 dp, 狀態 存放在二維數組中
dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j]
對dp二維數組初始化,將二維數組的最後一行用 原二維數組的最後一行進行初始化
//動態規劃
// dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j];
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle)
{
int len = triangle.size();
if(len <= 0)
return 0;
vector<vector<int>> dp(len, vector<int>(triangle[len-1].size()));
for(int i = 0; i < triangle[len-1].size(); i++) //初始一個dp 遞推必須的過程,要有遞推的原始值
dp[len -1][i] = triangle[len-1][i];
for(int i = len - 2; i >= 0; --i) //從倒數第一行向上遞推
{
for(int j = 0; j < triangle[i].size(); ++j)
{
dp[i][j] = triangle[i][j] + min(dp[i+1][j], dp[i+1][j+1]); //遞推方程
}
}
return dp[0][0]; //推到頂部就是路徑最小的和
}
};
Leetcode62. 不同的路徑 //動態規劃,較爲好理解的動態規劃 //dp[i][j] = dp[i][j-1] + dp[i-1][j]; ..這道題應該規劃爲簡單
//動態規劃,較爲好理解的動態規劃
//dp[i][j] = dp[i][j-1] + dp[i-1][j];
class Solution {
public:
int uniquePaths(int m, int n)
{
if(m <= 0 || n <= 0)
return 0;
vector<vector<int>> dp(m, vector<int>(n));
dp[0][0] = 1;
for(int i = 1; i < n; i++)
dp[0][i] = 1;
for(int j = 1; j < m; j++)
dp[j][0] = 1;
for(int i = 1; i < m; i++)
{
for(int j = 1; j < n; j++)
{
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
return dp[m-1][n-1];
}
};
Leetcode62. 不同的路徑 //動態規劃,較爲好理解的動態規劃 //dp[i][j] = dp[i][j-1] + dp[i-1][j];
只是動態規劃中要判斷路徑中有沒有存放石頭,起始路徑 和 終點是否是石頭,如果是直接返回0,路不通則爲0; 類型用long long 類型,int 會益處
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
long long m = obstacleGrid.size();
long long n = obstacleGrid[0].size();
if(m <= 0 || n <= 0 || obstacleGrid[m-1][n-1] == 1 || obstacleGrid[0][0])
return 0;
vector<vector<long long>> dp(m, vector<long long>(n, 0));
dp[0][0] = 1;
for(int i = 1; i < n; ++i) //初始 橫座標爲0 縱座標的值
{
if(obstacleGrid[0][i] == 1)
break;
else
dp[0][i] = 1;
}
for(int j = 1; j < m; ++j) //初始 縱爲0 橫座標的值
{
if(obstacleGrid[j][0] == 1)
break;
else
dp[j][0] = 1;
}
for(int i = 1; i < m; ++i)
for(int j = 1; j < n; ++j)
{
if(obstacleGrid[i][j] == 1) //判斷該節點有石頭 則路不通
dp[i][j] = 0;
else
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
return dp[m-1][n-1];
}
};