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

C++で解くキャンディ分配問題:隣接する子供の評価値に基づく最小キャンディ数の求め方

問題概要

N人の子供が一列に並んでおり、それぞれの子供には評価値(rating)が割り当てられています。これらの子供たちにキャンディを配る際、以下の条件を満たす必要があります。

  • すべての子供は最低1個のキャンディを受け取る必要があります。

  • 評価値が高い子供は、隣にいる子供よりも多くのキャンディを受け取る必要があります。

このとき、配るべきキャンディの最小個数を求めます。

例えば、入力が [1, 1, 3] の場合、出力は 4 となります。このとき、子供たちはそれぞれ 1個、1個、2個 のキャンディを受け取ることになります。

解法のアプローチ

この問題は、左から右、右から左の2回の走査(2パス方式)で効率的に解くことができます。手順は以下の通りです。

  1. 配列 ratings のサイズを n とし、サイズ n の配列 dp を作成して、すべての要素を 1 で初期化します(まず全員に1個ずつ配るため)。

  2. 変数 ret を 0 で初期化します。

  3. 左から右へ走査します(i を 1 から n - 1 まで)。

    • ratings[i] > ratings[i - 1] の場合、dp[i] := dp[i - 1] + 1 とします。

  4. 右から左へ走査します(i を n - 2 から 0 まで)。

    • ratings[i] > ratings[i + 1] の場合、dp[i] := max(dp[i], dp[i + 1] + 1) とします。

  5. ret := dp の全要素の合計とします。

  6. ret を返します。

C++による実装例

以下の実装例を見て、理解を深めましょう。

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   int candy(vector<int>& ratings) {
      int n = ratings.size();
      vector <int> dp(n, 1);
      int ret = 0;
      for(int i = 1; i < n; i++){
         if(ratings[i] > ratings[i - 1]){
            dp[i] = dp[i - 1] + 1;
         }
      }
      for(int i = n - 2; i >= 0; i--){
         if(ratings[i] > ratings[i + 1]){
            dp[i] = max(dp[i], dp[i + 1] + 1);
         }
      }
      for(int i = 0; i < n; i+=1){
         ret += dp[i];
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<int> v = {1,1,3};
   cout << (ob.candy(v));
}

入力

[1,1,3]

出力

4

計算量

このアルゴリズムの時間計算量は O(n)、空間計算量は O(n) です。配列を2回走査するだけで済むため、非常に効率的な解法となっています。

  1. C++で解くリスのナッツ収集シミュレーション ― 最小移動距離を求めるアルゴリズム

    問題概要 1本の木、1匹のリス、そして複数のナッツがフィールド上にあります。それぞれの位置は2次元グリッドのセルで表現されます。この問題の目的は、リスがすべてのナッツを集めて木の下に1個ずつ運ぶときの最小移動距離を求めることです。 リスの行動には次の制約があります。 一度に持てるナッツは最大1個 移動は上下左右の4方向で、隣接するセルへのみ可能 距離は移動回数(ステップ数)で表される たとえば、入力が「高さ: 5 / 幅: 7 / 木の位置: [2,2] / リスの位置: [4,4] / ナッツ: [[3,0], [2,5]]」の場合、出力は 12 となります。 解法のポイント まず、

  2. C++で解く長方形エリアII ― 座標圧縮と走査線法による被覆面積の計算

    問題概要 軸に平行な長方形のリストが与えられるものとします。各 rectangle[i] = {x1, y1, x2, y2} において、(x1, y1) は i 番目の長方形の左下隅の座標、(x2, y2) は右上隅の座標を表します。 求めたいのは、平面上でこれらすべての長方形が覆っている領域の合計面積です。答えは非常に大きな値になる可能性があるため、109 + 7 で割った余りを返すことになっています。 たとえば、入力が次のような場合を考えてみましょう。 このとき、出力は 6 となります。 解法の方針:座標圧縮+走査線(スイープライン) この問題は、座標圧縮(座標の離散化)と走査線法(