动态规划

使用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;
    }
};

相关链接
https://juejin.im/post/5a29d52cf265da43333e4da7
https://blog.csdn.net/u013309870/article/details/75193592

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值