动态规划之三:最长上升子序列与最长公共子序列问题

一.最长上升子序列

1.定义

LIS(i):表示以第i个数字为结尾的最长上升子序列的长度

LIS(i):表示在[0...i]的范围内,选择数字nums[i]可以获得的最长上升子序列的长度

LIS(i) = max(1 + LIS(j)) (i > j)


2.例题

300Longest Increasing Subsequence

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

Note:

  • There may be more than one LIS combination, it is only necessary for you to return the length.
  • Your algorithm should run in O(n2) complexity.
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) return 0;
        vector<int> memo(n+1, 1);
        for(int i = 1; i < n; i++){
            for(int j = 0; j < i; j++){
                if(nums[i] > nums[j]){
                    memo[i] = max(memo[i], 1 + memo[j]);
                }
            }
        }
        int res = memo[0];
        for(int i = 1; i < n; i++){
            res = max(res, memo[i]);
        }
        return res;
    }
};


二.最长公共子序列问题

1.定义

给出两个字符串S1和S2,求这两个字符串的最长公共子序列的长度

LCS(m,n) 是 S1[0...m] 和 S2[0...n]的最长公共子序列的长度

S1[m] == S2[n]:  LCS(m, n) = 1 + LCS(m-1, n-1)

S1[m] != S2[n]:  LCS(m, n) = max(LCS(m-1, n), LCS(m, n-1))

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;

class Solution {
public:
    int canPartition(vector<int>& nums1,vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        vector<vector<int> > memo(m, vector<int>(n, 0));
        if(nums1[0] == nums2[0]) memo[0][0] = 1;
        for(int i=1; i<m; i++){
            if(nums1[i] == nums2[0]) memo[i][0] = 1;
            memo[i][0] = max(memo[i-1][0], memo[i][0]);
        }
        for(int j=1; j<n; j++){
            if(nums2[j] == nums1[0]) memo[0][j] = 1;
            memo[0][j] = max(memo[0][j-1], memo[0][j]);
        }
        
        for(int i=1; i<m; i++){
            for(int j=1; j<n; j++){
                if(nums1[i] == nums2[j]) memo[i][j] = 1+ memo[i-1][j-1];
                else memo[i][j] = max(memo[i][j-1], memo[i-1][j]);
                printf("%d-%d-%d\n",i, j, memo[i][j]);
            }
        }
        return memo[m-1][n-1];
    }
};

int main(int argc, char **argv)
{
    Solution solution;
    vector<int> w;
    w.push_back(1);
    w.push_back(2);
    w.push_back(3);
    vector<int> w2;
    w2.push_back(1);
    w2.push_back(2);
    w2.push_back(3);
    w2.push_back(4);
    w2.push_back(2);
    w2.push_back(3);
    int res = solution.canPartition(w, w2);
    printf("%d\n",res);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013250416/article/details/80687416
今日推荐