• leetcode 动态规划类型题


    1,Triangle

    1 int mininumTotal(vector<vector<int>>& triangle)  {
    2     for (int i = triangle.size() - 2; i >= 0; --i) {  
    3         for (int j = 0; j < i + 1; ++j) {
    4             // 从下往上依次保存当前路径的最小值,上层只会用到下层的最小值
    5             triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
    6         }
    7     }
    8     return triangle[0][0];
    9 }
    triangle

     2,Maximum SubArray

     1 /*
     2  * 状态转移方程为:f[j] = max{ f[j-1] + S[j],S[j] },其中  1 <= j <= n
     3  *                 target = max{ f[j] },其中  1 <= j <= n
     4 */
     5 int maxArray(vector<int>& nums) {
     6     int n = nums.size();
     7     vector<int> dp(n + 1);
     8     dp[0] = 0;
     9     for (int i = 0; i < n; ++i) {
    10         dp[i + 1] = max(dp[i] + nums[i], nums[i]);
    11     }
    12     return *max_element(dp.begin(), dp.end());
    maxArray

    3,Palindromic Substrings

     1 /*
     2 * dp[i][j] 的值表示 s[i,j]这个字串是否为回文字符串
     3 */
     4 int countSubstrings(string& s) {
     5     int n = s.size();
     6     int res = 0;
     7     vector<vector<bool>> dp(n, vector<bool>(n, false));
     8     for (int i = n - 1; i >= 0; i--) {
     9         for (int j = i; j < n; ++j) {
    10             dp[i][j] = (s[i] == s[j] && (j - i <= 2 || dp[i + 1][j - 1]));
    11             if (dp[i][j]) res++;
    12         }
    13     }
    14     return res;
    15 }
    countSubstrings

     4,Palindromic Substrings(II)

     1 /*
     2 * p[i][j]用来判断 s[i][j]这个字串是否是回文子串
     3 * dp[i] 用来记录[0,i]这个范围内的最小切割数
     4 * 所以只用求 dp[n-1] 的值就是答案
     5 */
     6 int minCut(string& s) {
     7     if (s.empty()) return 0;
     8     int n = s.size();
     9     vector<vector<bool>> p(n, vector<bool>(n));
    10     vector<bool> dp(n);
    11 
    12     for (int i = 0; i < n; ++i) {
    13         dp[i] = i;  // 对 dp[i]初始化为最大切割数
    14         for (int j = 0; j <= i; ++j) {  // 对每一个子串s[i][j]进行遍历
    15             if (s[i] == s[j] && (i - j <= 2 || p[j + 1][i - 1])) {  // 如果s[j][i] 为回文子串
    16                 p[j][i] = true;
    17                 dp[i] = (j == 0) ? 0 : min(dp[i], dp[j - 1] + 1);
    18             }
    19         }
    20     }
    21     return dp[n - 1];
    22 }
    minCut

     5,Longest Common Substring

    1 /*
     2  × 求解最长公共子串(一定是连续才称为子串)
     3  × 初始化:dp[0][j] = 0;dp[i][0] = 0; 第0行全为0,第0列全为0
     4  ×                           0 ; (i==0 || j==0)
     5  * 状态转移方程: dp[i][j] = dp[i-1][j-1] + 1;   (s1[i] == s2[j])
     6  *                           0 ; (s1[i] != s2[j])
     7  × 结果:每次保存字符串长度的最大值即为所求
     8  */
     9 int lcs(string s1,string s2) {
    10     int len1 = s1.length();
    11     int len2 = s2.length();
    12     int res = 0;
    13     vector<vector<int>> dp(len1+1,vector<int>(len2+1,0));
    14 
    15     for(int i=1;i<=len1;++i) {
    16         for(int j=1;j<=len2;++j) {
    17             if(s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
    18             res = max(res,dp[i][j]);
    19         }
    20     }
    21     return res;
    22 }
    23 
    24 /*
    25  * 求解最长公共子序列(不一定连续)
    26  × 初始化:dp[0][j] = 0;dp[i][0] = 0;
    27  *                                 0;             (i == 0 || j == 0)
    28  × 状态转移方程:dp[i][j] =   dp[i-1][j-1] + 1;   (s1[i] == s2[j])
    29  *                          max(dp[i-1][j],dp[i][j-1]);(s1[i] != s2[j])
    30  * 结果:最后保存的 dp[len1][len2] 即为所求
    31  */
    32 int lcs(string s1,string s2) {
    33     int len1 = s1.length();
    34     int len2 = s2.length();
    35     vector<vector<int>> dp(len1+1,vector<int>(len2+1,0));
    36     
    37     for(int i=1;i<=len1;++i) {
    38         for(int j=1;j<=len2;++j) {
    39             if(s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
    40             else dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
    41         }
    42     }
    43     return dp[len1][len2];
    44 }
    
    lcs

     6: 最长连续递增序列

    //LongestIncrSequence 最长连续递增序列
    int LongestIncrSequence(vector<int> v) {
        int size = v.size();
        int maxLen = 1;
    //dp[i] 表示从下标 i 开始到末尾的最长连续递增序列 vector
    <int> dp(size, 1); for(int i=size-1; i>=0; i--) { for(int j=i+1; j<size; j++) { if(v[i] < v[j]) { dp[i] = max(dp[i], dp[j]+1); maxLen = max(maxLen, dp[i]); } } } return maxLen; }
    所有博文均为原著,如若转载,请注明出处!
  • 相关阅读:
    Android应用的跨语言调用小结
    用户体验技术优化系列(一)
    富客户端开发技术选型
    全年工作总结
    暗黑破坏神2:Tab打开地图就变卡顿解决办法
    winform使用post方式启动IE传递数据
    winform listbox 显示tooltip(防闪烁)
    android代码混淆
    android singleTask问题
    android在activity中锁屏解锁后重走OnCreate的问题的解决办法
  • 原文地址:https://www.cnblogs.com/zpcoding/p/10746370.html
Copyright © 2020-2023  润新知