# 动态规划（DP）算法

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

Example 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps


Example 2:

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

int climbStairs(int n) {
if(n==1||n==2){
return n;
}
return climbStairs(n-1)+climbStairs(n-2);
}

class Solution {
public:
int climbStairs(int n) {
vector<int>iteration(n+1,0); //initializition
iteration[1]=1;
iteration[2]=2;
int i=3;
while(i<n+1){
iteration[i]=iteration[i-1]+iteration[i-2];
i++;
}
return iteration[n];
}
};

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

1、根据题意分类讨论，分类讨论一定要达到引入i-1和i-2的解

2、挖掘i和i-1还有i-2之间的关系

3、边界条件确认

class Solution {
public:
int rob(vector<int>& nums) {
if(nums.empty()) return 0;
if(nums.size()==1) return nums[0];
vector<int>dp(nums.size(),0);
dp[0]=nums[0];
dp[1]=max(nums[0],nums[1]);
for(int i=2;i<nums.size();i++){
dp[i]=max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[nums.size()-1];
}
};

class Solution {
public:
int rob(vector<int>& nums) {
int size=nums.size();
if(size==0) return 0;
if(size==1) return nums[0];
if(size==2) return max(nums[0],nums[1]);
vector<int>a1(nums.begin(),nums.end()-1);
vector<int>a2(nums.begin(),nums.end()-2);
return max(rob(a1),rob(a2)+nums[size-1]);

}
};

三、最大子段和leetcode53

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

在分析问题的时候没有灵活变通，直接考虑前i个连续子数组数组的最大值，将无法进行分类讨论，无法得到递归关系，并且在考虑递归关系时也是直接考虑了i与i-1还有i-2之间的关系，其实可以考虑为i与i-1的关系即可，只要是一种可以迭代出所有情况的关系即可。在不能够得出迭代关系的时候需要变通的考虑，改变dp数组的意义，不需要一步到位，只要保证可以通过dp数组得到最后的结果即可。

code：dp数组表示的是以第i个元素结尾的连续子数组的最大值，最后再寻找dp的最大值

class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size=nums.size();
vector<int>dp(size,0);
dp[0]=nums[0];
for(int i=1;i<size;i++){
if(dp[i-1]>0) dp[i]=dp[i-1]+nums[i];
else dp[i]=nums[i];
}
int max1=dp[0];
for(int i=1;i<size;i++){
max1=max(max1,dp[i]);
}
return max1;
}
};

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)

Example 2:
coins = [2], amount = 3
return -1.

Note:
You may assume that you have an infinite number of each kind of coin.

....没有理解这道题果然写不出总结

class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int>dp(amount+1,amount+1);
dp[0]=0;
for(int i=1;i<=amount;i++){
for(int m:coins){
if(m<=i) dp[i]=min(dp[i],dp[i-m]+1);
}
}
if(dp.back()==amount+1) return -1;
else return dp.back();
}
};

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]


The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int size=triangle.size();
vector<vector<int>>dp(size,vector<int>(size,INT_MAX));
dp[0][0]=triangle[0][0];
for(int i=1;i<size;i++){
for(int j=0;j<triangle[i].size();j++){
if(j==0) dp[i][j]=dp[i-1][j]+triangle[i][j];
if(j==triangle[i].size()-1) dp[i][j]=dp[i-1][j-1]+triangle[i][j];
if(j!=0&&j!=triangle[i].size()-1) dp[i][j]=min(dp[i-1][j-1]+triangle[i][j],dp[i-1][j]+triangle[i][j]);
}
}
return *min_element(dp[size-1].begin(),dp[size-1].end());
}
};


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客