C++ 中,必须求前缀和前缀后给定元素的最大和递增子序列

c++server side programmingprogramming

在这个问题中,我们给定一个包含 N 个整数的数组 arr[] 和两个索引值 x 和 y。我们的任务是编写一个程序,根据前缀和前缀后给定元素,求出最大和的递增子序列。在 C++ 中,前缀和前缀后给定元素是必须的。

问题描述

我们将求出直到索引 x 的递增序列的最大和,包括索引 y 处的元素。

让我们举个例子来理解这个问题:

输入

arr[] = {1, 5, 9, 131, 6, 100, 11, 215}, x = 4, y = 6

输出

26

解释

我们将取直到索引 3 的子序列,最后包括 arr[6] = 11.

子序列为 {1, 5, 9, 11}。总和 = 1+5+9+11 = 26

解决方法

一种简单的方法是创建一个到 x 索引的新数组,然后将索引 y 处的元素添加到末尾。然后计算所有递增子序列,丢弃所有不包含元素 arr[y] 的子序列,并找到最大和。

另一种更有效的解决方法是使用动态规划方法。其思路是创建一个二维数组 DP[][],并存储递增子序列的最大和。DP[x][y] 处的值将给出到索引 x 处包含元素 arr[y] 的最大和。

示例

编写程序说明我们的解决方案的工作原理

#include <iostream>
using namespace std;
int DP[100][100];
void preCalcMaxSum(int arr[], int N){
   for (int i = 0; i < N; i++) {
      if (arr[i] > arr[0])
         DP[0][i] = arr[i] + arr[0];
      else
         DP[0][i] = arr[i];
   }
   for (int i = 1; i < N; i++) {
      for (int j = 0; j < N; j++) {
         if (arr[j] > arr[i] && j > i) {
            if (DP[i - 1][i] + arr[j] > DP[i - 1][j])
               DP[i][j] = DP[i - 1][i] + arr[j];
            else
               DP[i][j] = DP[i - 1][j];
         }
         else
            DP[i][j] = DP[i - 1][j];
      }
   }
}
int main() {
   int arr[] = {1, 5, 9, 131, 6, 100, 11, 215};
   int N = sizeof(arr) / sizeof(arr[0]);
   int x = 4, y = 6;
   preCalcMaxSum(arr, N);
   cout<<"前缀和前缀后给定元素的最大和为 <;
   cout<<DP[x][y];
   return 0;
}

输出

前缀和前缀后给定元素的最大和为 26

一种高效方法是求出到索引 x 的递增子序列的最大和,使得序列中的最大元素小于索引 y 处的元素。为此,我们将再次使用动态规划方法。

示例

程序演示我们的解决方案

#include <iostream>
using namespace std;
int calcMaxSum(int arr[], int n, int x, int y){
   int DP[x] = {0};
   int maxSum = -1;
   for (int i = 0; i <= x; i++)
      DP[i] = arr[i];
   for (int i = 0; i <= x; i++) {
      if (arr[i] >= arr[y]) {
         continue;
      }
      for (int j = 0; j < i; j++) {
         if (arr[i] > arr[j])
            DP[i] += arr[j];
            maxSum = max(maxSum, DP[i]);
      }
   }
   if (maxSum == -1) {
      return arr[y];
   }
   return maxSum + arr[y];
}
int main(){
   int arr[] = {1, 5, 9, 131, 6, 100, 11, 215};
   int N = sizeof(arr) / sizeof(arr[0]);
   int x = 4, y = 6;
   cout<<"前缀和前缀后的给定元素的最大和递增子序列必须是 ";
   cout<<calcMaxSum(arr, N, x, y);
   return 0;
}

输出

前缀和前缀后的给定元素的最大和递增子序列必须是 26

相关文章