动态规划

来源:互联网 发布:国外人工智能奖项 编辑:程序博客网 时间:2024/06/09 15:47

使用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]

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;    }};
0 0
原创粉丝点击