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

C++でストーンをマージするための最小コスト


N個の石の山が一列に並んでいると仮定します。ここで、i番目の山には石[i]個の石があります。移動は、K個の連続する杭を1つの杭にマージすることで構成されます。この移動のコストは、これらのK個の杭の石の総数に等しくなります。すべての石の山を1つの山に統合するための最小コストを見つける必要があります。そのような解決策がない場合は、-1を返します。

したがって、入力が[3,2,4,1]のようで、K =2の場合、出力は20になります。これは、[3、2、4、1]から開始するためです。次に、[3、2]を5のコストでマージすると、[5、4、1]が残ります。その後、5のコストで[4、1]をマージし、[5、5]が残ります。次に、[5、5]を10のコストでマージすると、[10]が残ります。つまり、総コストは20で、これが最小のコストです。

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

  • n:=石のサイズ

  • (n-1)mod(k-1)が0に等しくない場合、-

    • -1を返す

  • サイズn+1の配列プレフィックスを定義します

  • 初期化i:=1の場合、i <=nの場合、更新(iを1増やします)、実行-

    • prefix [i]:=prefix [i-1] + stones [i-1]

  • サイズnxn

    の2D配列dpを1つ定義します。
  • 長さの初期化:=kの場合、長さ<=nの場合、更新(長さを1増やします)、実行-

    • 初期化i:=0、j:=長さ-1の場合、j

    • dp [i、j]:=inf

    • mid:=iを初期化する場合、mid

      • dp [i、j]:=最小のdp [i、j]およびdp [i、mid] + dp [mid + 1、j]

    • (j --i)mod(k --1)が0と同じ場合、-

      • dp [i、j]:=dp [i、j]+プレフィックス[j+1]-プレフィックス[i]

  • dp [0、n-1]

    を返します

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   int mergeStones(vector<int>& stones, int k){
      int n = stones.size();
      if ((n - 1) % (k - 1) != 0)
      return -1;
      vector<int> prefix(n + 1);
      for (int i = 1; i <= n; i++) {
         prefix[i] = prefix[i - 1] + stones[i - 1];
      }  
      vector<vector<int>> dp(n, vector<int>(n));
      for (int length = k; length <= n; length++) {
         for (int i = 0, j = length - 1; j < n; i++, j++) {
            dp[i][j] = INT_MAX;
            for (int mid = i; mid < j; mid += k - 1) {
               dp[i][j] = min(dp[i][j], dp[i][mid] + dp[mid +
               1][j]);
            }
            if ((j - i) % (k - 1) == 0) {
               dp[i][j] += prefix[j + 1] - prefix[i];
            }
         }
      }
      return dp[0][n - 1];
   }
};
main(){
   Solution ob;
   vector<int> v = {3,2,4,1};
   cout << (ob.mergeStones(v, 2));
}

入力

{3,2,4,1}, 2

出力

20

  1. C++でボードを正方形にカットするための最小コスト

    コンセプト 長さp、幅qのボードが与えられたとすると、破壊のコストが最小になるように、このボードをp*qの正方形に分割する必要があります。このボードでは、各エッジの切削コストが示されます。一言で言えば、コストが最小になるように、このような一連の切断を選択する必要があります。 例 上記のボードに関して、正方形にカットする最適な方法は-です。 上記の場合の合計最小コストは65です。これは、次の手順を実行して計算され、評価されます。 Initial Value : Total_cost = 0 Total_cost = Total_cost + edge_cost * total_pi

  2. C++での最小の騎士の動き

    座標が-無限大から+無限大までの無限のチェス盤があり、正方形[0、0]に騎士がいるとします。騎士は、以下に示すように、8つの可能な動きをすることができます。それぞれの動きは、基本方向に2マス、次に直交方向に1マスです。 騎士を正方形[x、y]に移動するために必要な最小ステップ数を見つける必要があります。答えが存在することが保証されています。 したがって、入力がx=5およびy=5の場合、出力は4になります。これは[0,0]→[2,1]→[4,2]→[3,4]→[のようになります。 5,5] これを解決するには、次の手順に従います- マップを定義するm Solve()とい