C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++での3つの重複しないサブ配列の最大合計


正の整数のnumsと呼ばれる1つの配列があるとすると、合計が最大の3つの重複しないサブ配列を見つける必要があります。ここでは、各サブ配列のサイズはkであり、すべての3*kエントリの合計を最大化する必要があります。

結果は、各区間の開始位置を表すインデックスのリストとして見つける必要があります。複数の回答がある場合は、辞書式順序で最小のものを返します。

したがって、入力が[1,2,1,2,6,8,4,1]のようで、k =2の場合、結果は[0,3,5]になるため、サブ配列は[1,2]、 [2,6]、[8,4]は開始インデックス[0,3,5]に対応します。

これを解決するには、次の手順に従います-

  • n:=numsのサイズ
  • サイズ3の配列retを定義し、これをinfで埋めます
  • サイズn+1の配列の合計を定義します
  • iを初期化する場合:=0、i
  • sum [i + 1] =sum [i] + nums [i]
  • サイズnの配列posLeftを定義します
  • サイズnの配列posRightを定義します。これをn-kで埋めます
  • iを初期化する場合:=k、currMax:=sum [k]-sum [0]、i
  • newTotal:=sum [i + 1] --sum [i + 1 --k]
  • newTotal> currMaxの場合、-
    • currMax:=newTotal
    • posLeft [i]:=i + 1 --k
  • それ以外の場合
    • posLeft [i]:=posLeft [i-1]
  • iを初期化する場合:=n --k-1、currMax:=sum [n] --sum [n --k]、i> =0の場合、更新(iを1つ減らす)、実行-
    • newTotal:=sum [i + k]-sum [i]
    • newTotal> =currMaxの場合、-
      • currMax:=newTotal
      • posRight [i]:=i
    • それ以外の場合
      • posRight [i]:=posRight [i + 1]
  • req:=0
  • iを初期化する場合:=k、i <=n-2 * kの場合、更新(iを1つ増やす)、実行-
    • l:=posLeft [i-1]、r:=posRight [i + k]
    • temp:=(sum [l + k] --sum [l])+(sum [i + k] --sum [i])+(sum [r + k] --sum [r])
    • >
    • temp> reqの場合、-
      • ret [0]:=l、ret [1]:=i、ret [2]:=r
      • req:=temp
  • return ret
  • 理解を深めるために、次の実装を見てみましょう-

    #include <bits/stdc++.h>
    using namespace std;
    void print_vector(vector<auto> v){
       cout << "[";
       for(int i = 0; i<v.size(); i++){
          cout << v[i] << ", ";
       }
       cout << "]"<<endl;
    }
    class Solution {
    public:
       vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
          int n = nums.size();
          vector <int> ret(3, INT_MAX);
          vector <int> sum(n + 1);
          for(int i = 0; i < n; i++){
             sum[i + 1] = sum[i] + nums[i];
          }
          vector <int> posLeft(n);
          vector <int> posRight(n, n - k);
          for(int i = k, currMax = sum[k] - sum[0]; i < n; i++){
             int newTotal = sum[i + 1] - sum[i + 1- k];
             if(newTotal > currMax){
                currMax = newTotal;
                posLeft[i] = i + 1 - k;
             }else{
                posLeft[i] = posLeft[i - 1];
             }
          }
          for(int i = n - k - 1, currMax = sum[n] - sum[n - k]; i >=0 ; i--){
             int newTotal = sum[i + k] - sum[i];
             if(newTotal >= currMax){
                currMax = newTotal;
                posRight[i] = i;
             }else{
                posRight[i] = posRight[i + 1];
             }
          }
          int req = 0;
          for(int i = k; i <= n - 2 * k; i++){
             int l = posLeft[i - 1];
             int r = posRight[i + k];
             int temp = (sum[l + k] - sum[l]) + (sum[i + k] - sum[i]) + (sum[r + k] - sum[r]);
             if(temp > req){
                ret[0] = l;
                ret[1] = i;
                ret[2] = r;
                req = temp;
             }
          }
          return ret;
       }
    };
    main(){
       Solution ob;
       vector<int> v = {1,2,1,2,6,8,4,1};
       print_vector(ob.maxSumOfThreeSubarrays(v, 2));
    }

    入力

    {1,2,1,2,6,8,4,1}
    2

    出力

    [0, 3, 5, ]

    1. C++の三角形の最大パス合計

      この問題では、三角形の形の数字が与えられます。私たちのタスクは、三角形の最大パス合計を見つけるプログラムを作成することです。 要素は、最初の行から1つの要素で始まり、次の行で要素の数を増やして、n番目の行に要素が入るまで配置されます。 したがって、プログラムは、三角形の要素の最大合計を提供するパスを見つけます。したがって、最大の合計を提供するパスを見つける必要があります。 問題を理解するために例を見てみましょう- 入力 −   1  5 6 8 2 9 出力 − 16 説明 − 上からのパスは最大合計を返します− 9 + 6 + 1 =16 この問題を

    2. C++でのサイズKのM個の重複しないサブ配列の最大合計

      問題の説明 配列と2つの数値MおよびKが与えられます。配列内で、サイズK(重複しない)の最大M個のサブ配列の合計を見つける必要があります。 (配列の順序は変更されません)。 Kはサブアレイのサイズ、Mはサブアレイの数です。配列のサイズはm*kより大きいと想定できます。配列の合計サイズがkの倍数でない場合は、最後の配列の一部を取得できます。 例 指定された配列が={2、10、7、18、5、33、0}の場合。 N =7、M =3、K =1の場合、サブセットは-であるため、出力は61になります。 {33, 18, 10} アルゴリズム presum配列を作成します。これには、指定された配列の