C++算法学习(动态规划算法)

1、目标

是求解决策过程最优化的过程。

2、方法

把原问题分解成子问题进行求解,也就是分治的思想。

3、过程

主要分四步:

  1. 划分子问题:把一个大问题分解为小问题
  2. 状态表示:如何处理小问题。
  3. 状态转移:也就是父问题如何推导出子问题。
  4. 确定边界:确定初始状态是什么?最小的子问题?最终状态又是什么。

4、例题

(1)力扣:5. 最长回文子串

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
    int length = s.length();
     vector<vector<bool>> answer(length, vector<bool>(length));
    int Start = 0,End = 0;
    //自己与自己的关系全部设为true,也就是只有一个的情况
    for(int i = 0;i < length;i++){
    
    
        answer[i][i] = true;
    }
    //开始进行遍历,达到条件的就改成true
    for(int j = 1;j < length;j++){
    
    
        for(int i = 0;i < j;i++){
    
    
            if(s.at(i) == s.at(j) &&(i+1 == j || answer[i+1][j-1]))
            {
    
    
               if(j - i >= End - Start){
    
    
                   Start = i;
                   End = j;
               }
               answer[i][j] = true;
            }
        }
    }
    return s.substr(Start,(End - Start + 1));
    }
};

ps:我在刷这一部分题的时候遇见的问题很大,做起来很困难,唉。

(1)力扣:1018. 可被 5 整除的二进制前缀

打个比方[0,1,1,1],第一个数是0,第二个数是01,第三个是011,第四个是0111,化为十进制,分别为0,1,3,7.然后根据二进制规则,数据每向左移动一位,数据大小乘2.
那么可以用sum = 0, sum = sum *2 + num。num就是[0,1,1,1]里的元素,sum就是化成的十进制。

class Solution {
    
    
public:
    vector<bool> prefixesDivBy5(vector<int>& A) {
    
    
      vector<bool> a;
    int sum = 0;
    for(auto num : A){
    
    
        sum = sum * 2 +num;
        cout<<sum % 5<<endl;
        if(sum % 5 == 0) a.push_back(1);
        else if(sum % 5 != 0 ) a.push_back(0);
    }
    return a;
    }
};

然后运行超时了所以我准备改造一下
首先sum*2我们可以改造成sum<<1,直接改成二进制移动位置,然后可以让sum等于之前sum留下的余数

class Solution {
    
    
public:
    vector<bool> prefixesDivBy5(vector<int>& A) {
    
    
      vector<bool> a;
    int sum = 0;
    for(auto num : A){
    
    
        sum = (sum << 1) +num;
        a.push_back(sum % 5 == 0);    
    }
    return a;
    }
};

然后又报错int类型的数据的存储空间不够,那就想办法让int存的小一点.

class Solution {
    
    
public:
    vector<bool> prefixesDivBy5(vector<int>& A) {
    
    
      vector<bool> a;
    int sum = 0;
    for(auto num : A){
    
    
        sum = ((sum << 1) +num) %5;
        a.push_back(sum == 0);    
    }
    return a;
    }
};

每次sum都除一下5让sum只等于他的余数,因为多余的数怎么也是五的倍数,关键就是看余出来的这一部分数据能够怎么处理。

猜你喜欢

转载自blog.csdn.net/weixin_45743162/article/details/110870972