动态规划非常多在数组中取一定条件子集的题
动态规划最重要的还是要找到状态方程
股票买卖问题
股票买卖是非常经典的动态规划的题
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
这是股票买卖的动态方程:
for(int i=1;i<prices.length;i++){
max = Math.max(max,prices[i]-min);
min = Math.min(min,prices[i]);
}
- max为现有选取所选取的最大利润,prices[i]-min现在所计算的利润,如果max大则最大利润不变,如果后者大,说明现在是最大的利润
- min为求得最小值,只有最大数减去最小数才会得到最大的利润
股票问题最重要的就是求的最大最小值,这在动态规则中非常常见
求最大子集和问题
这道题同样也是非常典型的动态规划问题
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
这是动态方程:
for(int i = 1;i<nums.length;i++){
dp[i] = Math.max (dp[i-1]+nums[i],nums[i]);
max = Math.max(max,dp[i]);
}
这道题也是找最大值的问题,和上面一题不同,这道题不需要找最小值,并且子集是连续的,我需要通过不断累加来比较大小
dp[i]是n=1时的最大子集,dp[i-1]+nums[i],与==nums[i]==做比较,是为了查看是否需要加上当前元素,如过加上当前元素更大,则取前者,反之取当前元素
max的取值是在已报保存的max 以及 取到i时的数组谁大,这个是更新max的取值,
最长递增子序列
for(int i = 1;i<nums.length;i++){
for(int j = 0;j<i;j++){
if(nums[j] < nums[i]){
dp[i] = Math.max(dp[j]+1,dp[i]);
}
}
res = Math.max(res, dp[i]);
}
最长递增子序列需要定义一个数组dp[ ],这个数组初始值为0,说明至少有一个递增子序列(元素本身),dp[i]代表以num[i]为结尾元素的最大递增子序列个数,随着遍历,dp[i]是在不断变大的dp[i]+1是加上了元素本身
如果不清楚的可以在这个进行动态演示
https://alchemist-al.com/algorithms/longest-increasing-subsequence.