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

C++でのK個の等和サブセットへの分割


numsと呼ばれる整数の配列と正の整数kがあるとします。この配列を、合計がすべて同じであるk個の空でないサブセットに分割できるかどうかを確認します。したがって、配列が[4,3,2,3,5,2,1]のようで、k =4の場合、指定された配列は[[5]、[ 1,4]、[2,3]、[2,3]]の合計は等しい。

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

  • dpと呼ばれる2つのテーブルと合計サイズ2^nを定義します。
  • 指定された配列numsを並べ替え、sum:=nums配列内のすべての要素の合計を設定します
  • summodkが0以外またはnumsの最後の要素>sum/ kの場合、falseを返します
  • set dp [0]:=true and sum:=sum / k
  • 0〜2^nの範囲のiの場合
    • dp [i]がゼロ以外の場合、
      • 0〜の範囲のjの場合、
        • temp:=i OR 2 ^ j
        • tempがiと同じでない場合、
          • nums [j] <=sum – total [i] mod sumの場合、dp [temp]:=true
          • total [temp]:=total [i] + nums [j]
        • それ以外の場合はループから出てきます
  • return dp [(2 ^ n)-1]
例(C ++)

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

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   bool canPartitionKSubsets(vector<int>& nums, int k) {
      int n = nums.size();
      vector <bool> dp(1 << n);
      vector <int> total(1 << n);
      sort(nums.begin(), nums.end());
      int sum = 0;
      for(int i = 0; i < nums.size(); i++)sum += nums[i];
      if(sum % k || nums[nums.size() - 1] > sum / k) return false;
      dp[0] = true;
      sum /= k;
      for(int i = 0; i < (1 << n); i++){
         if(dp[i]){
            for(int j = 0; j < n; j++){
               int temp = i | (1 << j);
               if(temp != i){
                  if(nums[j] <= sum - (total[i] % sum)){
                     dp[temp] = true;
                     total[temp] = total[i] + nums[j];
                  }
                  else{
                     break;
                  }
               }
            }
         }
      }
      return dp[(1 << n) - 1];
   }
};
main(){
   Solution ob;
   vector<int> v = {4,3,2,3,5,2,1};
   cout << (ob.canPartitionKSubsets(v, 4));
}

入力

[4,3,2,3,5,2,1]
4

出力

1

  1. C++でセットをk個のサブセットに分割する方法の数を数えます

    与えられた2つの数字eとp。目標は、セットのe個の要素をp個のパーティション/サブセットに分割できる方法の数を数えることです。 例 入力 e=4 p=2 出力 Count of number of ways to partition a set into k subsets are: 7 説明 If elements are: a b c d then ways to divide them into 2 partitions are: (a,b,c)−(d), (a,b)−(c,d), (a,b,c)−(d), (a)−(b,c,d), (

  2. C++での等しいツリーパーティション

    n個のノードを持つ二分木があるとすると、元のツリーの1つのエッジを削除した後、値の合計が等しい2つのツリーにツリーを分割できるかどうかを確認するタスクがあります。 したがって、入力が次のような場合 そうすれば、出力は真になります。 これを解決するには、次の手順に従います- 1つのスタックstを定義する 関数solve()を定義します。これはノードを取ります ノードがnullの場合、- 0を返す leftSum:=solve(ノードの左側) rightSum:=solve(ノードの権利) curr:=val + leftSum+rig