动态规划
2016-07-07 16:42
429 查看
使用Dynamic Programming 的条件
1)优化子结构:一个问题的优化解包含子问题的优化解
2)重叠子问题:在问题的求解过程中,很多子问题被多次使用
算法设计步骤
*分析优化解的结构:划分子问题、优化子结构、子问题重叠性
*建立优化解的代价递归方程
*递归的划分子问题,直至不可划分
*自底向上计算优化解的代价,记录优化解的构造信息
*构造优化解
最短路径问题
1:划分d(S,T)为3个子问题
d(S,T)=min{1+d(A,T), 2+d(B,T), 5+d(C,T)}
2:划分d(A,T), d(B,T), d(C,T)为6个子问题
3:求解最小子问题
d(A,T)=min{4+d(D,T),11+d(E,T)}=min{22,12}=12
d(B,T)=min{9+d(D,T), 5+d(E,T), 16+d(F,T)}=min{27,6,18}=6
d(C,T)=min{2+d(F,T)}=4
4:确定最后最短路径
d(S,T)=min{1+d(A,T), 2+d(B,T), 5+d(C,T)}=min{23,8,9}=8 (S,B,E,T)
动态规划相关问题
1 最长公共子序列
2 矩阵链乘法
3 Optimal Polygon Triangulation
4 0/1背包问题
5 The Optimal Binary Search Trees
6 leetcode上的题368. Largest Divisible Subset,之前没想到用动态规划,后来发现用动态规划更简单
Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0.
If there are multiple solutions, return any subset is fine.
Example 1:
nums: [1,2,3]
Result: [1,2] (of course, [1,3] will also be ok)
Example 2:
nums: [1,2,4,8]
Result: [1,2,4,8]
1)优化子结构:一个问题的优化解包含子问题的优化解
2)重叠子问题:在问题的求解过程中,很多子问题被多次使用
算法设计步骤
*分析优化解的结构:划分子问题、优化子结构、子问题重叠性
*建立优化解的代价递归方程
*递归的划分子问题,直至不可划分
*自底向上计算优化解的代价,记录优化解的构造信息
*构造优化解
最短路径问题
1:划分d(S,T)为3个子问题
d(S,T)=min{1+d(A,T), 2+d(B,T), 5+d(C,T)}
2:划分d(A,T), d(B,T), d(C,T)为6个子问题
3:求解最小子问题
d(A,T)=min{4+d(D,T),11+d(E,T)}=min{22,12}=12
d(B,T)=min{9+d(D,T), 5+d(E,T), 16+d(F,T)}=min{27,6,18}=6
d(C,T)=min{2+d(F,T)}=4
4:确定最后最短路径
d(S,T)=min{1+d(A,T), 2+d(B,T), 5+d(C,T)}=min{23,8,9}=8 (S,B,E,T)
动态规划相关问题
1 最长公共子序列
2 矩阵链乘法
3 Optimal Polygon Triangulation
4 0/1背包问题
5 The Optimal Binary Search Trees
6 leetcode上的题368. Largest Divisible Subset,之前没想到用动态规划,后来发现用动态规划更简单
Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0.
If there are multiple solutions, return any subset is fine.
Example 1:
nums: [1,2,3]
Result: [1,2] (of course, [1,3] will also be ok)
Example 2:
nums: [1,2,4,8]
Result: [1,2,4,8]
class Solution { public: vector<int> largestDivisibleSubset(vector<int>& nums) { vector<int> result; if(nums.size()==0) return result; int len = nums.size(); vector<int> num_index(len,-1),num_dp(len,1); int max_dp=1,max_index=0; //sort(nums.begin(),nums.end(),greater<int>()); sort(nums.begin(),nums.end()); for(int i=0;i<len;i++) for(int j=i-1;j>-1;j--) { if(nums[i]%nums[j]==0 && num_dp[j]+1>num_dp[i]) { num_dp[i]=num_dp[j]+1; num_index[i]=j; } if(max_dp<num_dp[i]) { max_dp = num_dp[i]; max_index=i; } } for(;max_index!=-1;max_index=num_index[max_index]) result.push_back(nums[max_index]); return result; } };
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法