动态规划——最大上升子序列和

题目:

一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ...,aN),
我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中序列和最大为18,为子序列(1, 3, 5, 9)的和. 你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和为100,而最长上升子序列为(1, 2, 3)。

code:

import java.util.Scanner;
     
public class Main7 {
        public static void main(String[] args) {
            Scanner s = new Scanner(System.in);
             
            int n = s.nextInt();
             
            int[] ar = new int[n];          /*         使用对应的数组记录每个位置上升子序列的最大值            */
            int[] br = new int[n];
            int max = 0;
            for(int i=0;i<n;i++) {
                ar[i] = s.nextInt();
                if(i==0) {                    //初始化
                    br[i] = ar[0];
                    max = br[0];
                }else {
                    int sum = 0; //记录当前位置i的最大升序列和
                    int j=i-1;
                    for(;j>=0 && (ar[j]>=ar[i]);j--);
                    if(j>=0) {
                        int temp = ar[j];
                        sum = br[j];
                        for(--j;j>=0;j--) {                              //i位置之前的降序序列
                            if(ar[j]<ar[i] && ar[j]>temp) {
                                temp = ar[j];
                                sum = sum>br[j]?sum:br[j];
                            }
                        }
                    }
                    br[i] = sum+ar[i]; //在br数组中记录当前i位置的最大序列和
                    max = max>br[i]?max:br[i];//更新max的值
                }
            }
            System.out.println(max);
        }
    }

  思想:查找某位置的最大上升子序列,需要找到该位置之前的最大上升子序列。而该位置之前可能存在多个子序列,且每个子序列的末尾元素构成一个降序序列。所以需要将每个降序序列记录的最大值分别与当前查找位置的值相加后比较。

原文地址:https://www.cnblogs.com/dream-flying/p/12780326.html