# [LeetCode] 动态规划入门题目

1.Jump Game

class Solution {
public:
bool canJump(vector<int>& nums) {
int reach = 0;
for (int i = 0; i < nums.size() - 1 && reach >= i; i++) {
reach = nums[i] + i > reach ? nums[i] + i : reach;
}
return reach >= nums.size() - 1;
}
};

2.Maximum Subarray

class Solution {
public:
int maxSubArray(vector<int>& nums) {
int global = nums[0], local = nums[0];
for (int i = 1; i < nums.size(); i++) {
local = nums[i] > nums[i] + local ? nums[i] : nums[i] + local;
global = local > global ? local : global;
}
return global;
}
};

3.Best Time to Buy and Sell Stock

（1）

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) return 0;
int maxPrice = prices[prices.size() - 1];
int res = 0;
for (int i = prices.size() - 1; i >= 0; i--) {
maxPrice = max(maxPrice, prices[i]);
res = max(res, maxPrice - prices[i]);
}
return res;
}
};

（2）局部最优和全局最优解法：

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) return 0;
int local = 0, global = 0;
for (int i = 1; i < prices.size(); i++) {
local = max(0, local + prices[i] - prices[i - 1]);
global = max(local, global);
}
return global;
}
};
local = max(0, local + prices[i] - prices[i - 1])这一句，我一开始在考虑：为什么不写成local = max(local, local + prices[i] - prices[i - 1])呢？后来想了一下，因为假如这样写，有可能得到的就不是包含当前元素的局部最优解了。所以，在“局部最优和全局最优解法”里面，永远不会出现local=local的情况。4.Minimum Path Sum原题地址：https://leetcode.com/problems/minimum-path-sum/description/这道题目不需用到上面的“局部最优和全局最优”解法，只需要每次选出最优的即可。除了边界的元素，其他元素的最优都是 min{min[i - 1][j] + grid[i][j],min[i][j - 1] + grid[i][j]}。
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int ** min  = new int*[grid.size()];
for (int i = 0; i < grid.size(); i++) {
min[i] = new int[grid[i].size()];
}
min[0][0] = grid[0][0];
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[i].size(); j++) {
if (i == 0 && j == 0) continue;
else if (i == 0) min[i][j] = min[i][j - 1] + grid[i][j];
else if (j == 0) min[i][j] = min[i - 1][j] + grid[i][j];
else min[i][j] = min[i - 1][j] + grid[i][j] < min[i][j - 1] + grid[i][j] ? min[i - 1][j] + grid[i][j] : min[i][j - 1] + grid[i][j] ;
}
}
return min[grid.size() - 1][grid[grid.size() - 1].size() - 1];
return 0;
}
};

5.Triangle地址：https://leetcode.com/problems/triangle/description/也是一道典型的dp题目，思想跟上面一题差不多：
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
if (triangle.size() == 1) return triangle[0][0];
int ** min = new int *[triangle.size()];
for (int i = 0; i < triangle.size(); i++) {
min[i] = new int[triangle[i].size()];
}
min[0][0] = triangle[0][0];
int res = INT_MAX;
for (int i = 0; i < triangle.size(); i++) {
for (int j = 0; j < triangle[i].size(); j++) {
if (i == 0 && j == 0) continue;
else if (j == 0) min[i][j] = min[i - 1][j] + triangle[i][j];
else if (j == triangle[i].size() - 1) min[i][j] = min[i - 1][j - 1] + triangle[i][j];
else min[i][j] = min[i - 1][j - 1] + triangle[i][j] < min[i - 1][j] + triangle[i][j] ? min[i - 1][j - 1] + triangle[i][j] : min[i - 1][j] + triangle[i][j];
if (min[i][j] < res && i == triangle.size() - 1) {
res = min[i][j];
}
}
}
return res;
}
};
但这道题有趣的地方在于，空间复杂度可以缩小到O(n)：我们把这个三角形倒过来看，便能发现可以通过复用一个一维数组来储存最小值：
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
vector<int> min = triangle[triangle.size() - 1];
for (int i = triangle.size() - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
min[j] = min[j] < min[j + 1] ? min[j] + triangle[i][j] : min[j + 1] + triangle[i][j];
}
}
return min[0];
}
};

posted @ 2017-09-29 21:40  fengzw  阅读(4074)  评论(0编辑  收藏  举报