动态规划

动态规划

2019-05-12  本文已影响1人  别时茫茫

动态规划

标签(空格分隔): algorithm
作业部落地址:https://www.zybuluo.com/LIUHUAN/note/1465029


最长连续递增子序列

1、思路一

int findLengthOfLCIS(vector<int>& nums) {
        int n = nums.size();
        if(n <= 1)
            return n;
        int maxlen = 1;
        for(int i = 0; i < n;i++ )  {
            int len = 1;// 每次nums[i] 开始的序列最大长度为1,往后增长
            for(int j = i+ 1;j < n;j++){
            if(nums[j] > nums[j-1] ) {// 连续递增
                len += 1; // 长度增加
                maxlen = max(maxlen,len);
            }else {// 不连续递增了,下一个元素继续计算
                break;
            }
        }
        return maxlen;
    }

2、思路2

dp[i+1] = \left\{\begin{matrix} dp[i] +1 & if & nums[i+1] > nums[i] \\ 1 & else \end{matrix}\right.

int findLengthOfLCIS(vector<int>& nums) {
        int n = nums.size();
        if(n <= 1)
            return n;
        vector<int> dp(n,1);
        int maxlen = 1;
        for(int i = 1; i < n; i++ )  {
            if( nums[i] > nums[i-1] ) {
                dp[i] = dp[i-1] + 1 ;
            }
            maxlen = max( dp[i] , maxlen );
        }
        return maxlen;
    }


最长递增子序列

1、思路1

int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        if(n <= 1 )
            return n;
        vector<int> dp(n,1);// 初始化为1
        int max_len = 1;
        for(int i = 1 ;i < n; i++) {
            for(int j = i-1 ;j >=0 ;j-- ) { // 遍历[0,i-1]的元素加上nums[i] 之后的长度是否构成更长的递增子序列
                if(nums[j] < nums[i]) {
                    dp[i] = max(dp[i],dp[j] + 1 );
                    max_len = max(max_len,dp[i]);
                }
            }
        }
        return max_len;
    }

最长递增子序列的数量

1、思路1

int findNumberOfLIS(vector<int>& nums) {
        int n = nums.size();
        if(n <= 1)
            return n;
        vector<int> dp(n,1); // nums[i]结尾的最长递增子序列长度
        int max_len = 1;//最大长度
        vector<int> max_c(n,1);// 每个最长子序列的长度默认为1
        for(int i = 1; i < n; i++ ){                                 
            for(int j = i - 1; j >= 0; j-- ) {
                if(nums[i] > nums[j]) {
                    if(dp[i] < dp[j] + 1){// dp[i] 可以从dp[j] 扩展得到更长的子序列,那么最长子序列的个数就是扩展前dp[j]的个数,max_c[j]
                        max_c[i] = max_c[j]; // 扩展后的来源个数
                    }else if(dp[i] == dp[j] + 1) { // 相同长度的其他扩展而来的子序列 
                        max_c[i] += max_c[j] ; // 因为长度相同,所以求和来源的个数
                    }
                    dp[i] = max(dp[i],dp[j] + 1);
                    max_len = max(dp[i],max_len);
                }
            }
        }
        // 遍历所有的dp[i]等于最大长度时,求和所有的max_c[i],得到最大长度递增子序列的个数和
        int maxc = 0;
        for(int i = 0; i < n ; i++) {
            if(dp[i] == max_len) {
                maxc += max_c[i];
            }
        }
        return maxc;
    }

最长配对链

思路1

int findLongestChain(vector<vector<int>>& pairs) {
        int n = pairs.size();
        if(n <= 1)
            return n;
        sort(pairs.begin(),pairs.end(),[](vector<int>& a,vector<int>&b ){return a[0] < b[0];});
        vector<int> dp(n,1);
        int max_len = 1;
        for(int i =1;i < n; i++) {
            int ifirst = pairs[i][0];
            for(int j =i -1 ;j >= 0; j--) {
                if(pairs[j][1] < ifirst) { // 构成递增链
                    dp[i] = max(dp[i],dp[j] + 1); //更新递增链大小
                    max_len = max(max_len,dp[i]);
                }
            }
        }
        return max_len;
    }
上一篇 下一篇

猜你喜欢

热点阅读