动态规划系列学习总结一

2021-07-11  本文已影响0人  dajielailin

动态规划简介

动态规划思想

1. 算法思想:若要解决一个给定问题,可以先解其子问题,然后根据子问题的解组合出原问题的解;

2. 实质:

找出子问题和原问题的关系——最优子结构;

以及子问题之间的关系——重复子问题。

最优子结构:

    定义记忆化数组dp[n],使用dp[i]-表示以数组A[i]结尾的最长子序列长度;
    则对dp[i],若存在0 <= j < i,且A[i] > A[j],则dp[i] = max(dp[i], dp[j] + 1), 即:
    dp[n] = max{0<= j < i, dp[j] + 1},
    而数组A的最大递增子序列长度 = max(dp[i]);

重复子问题:


二分法实战笔记

二分法的应用场景

  1. 查询固定值在数组中的位置;
  2. 求固定值在数组中的上界;
  3. 求固定值在数组中的下界;

二分法实现细节

下面以查找固定值在数组中的上界为例,展示代码细节:

int findUpValue(int num, vector<int>& dp)
{
    int left = 0, right = dp.size() - 1;
    while(left <= right) //=号保证数组的左右边界都能遍历到
    {
        int mid = left + (right - left) / 2; //(left + right)/ 2可能导致int类型溢出
        if(dp[mid] == num)
        {
            left = mid + 1;
        }
        else if(dp[mid] > num)
        {
            right = mid - 1;    //应对 num < dp[0]
        }
        else
        {
            left = mid + 1;     //应对 num > dp[dp.size() - 1]
        }
    }
    if(left < dp.size())    //如果求num在数组中的上界,那么当循环退出时,dp[left]不再 <= num
    {                       //如果求num在数组中的下界,那么当循环退出时,dp[right]不再 > num
        return dp[left];
    }
    return -1;  //如果left >= dp.size(),代表数组中没有区间 > num
}
上一篇 下一篇

猜你喜欢

热点阅读