【问题标题】:SubsetSum Printing the listSubsetSum 打印列表
【发布时间】:2013-10-07 22:01:25
【问题描述】:

问题是打印总和为一个值的所有子集。我编写了代码来检查是否存在可能的子集。有人能给我一个想法来打印构成总和的数字吗?下面是我的代码。为简单起见,假设数组仅包含 +ve nos。

void subsetsum(int A[], int target) {

int N = sizeof(A)/sizeof(int), sum = 0;

for(int i = 0; i < N; i++) sum += A[i];

vector<bool> V(sum + 1, 0);
V[0] = 1;
for(int i = 0; i < N; i++) 
   for(int j = sum; j >= 0; j--) {
      if(j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
   }
  if(V[target]) cout << "Sumbset sum exists" << endl;
  else cout << "Sumbset sum doesnt exist" << endl;
}

【问题讨论】:

    标签: c++ algorithm dynamic-programming


    【解决方案1】:

    首先你需要生成所有的子集

    如果给定数组 [a,b,c,d],请考虑生成子集,一次从数组中获取每个元素。

    子集(X),包括 y = foreach x in X append y to x

    取a,我们得到subsets(a) = { [], [a] }

    取b,我们得到subsets(a,b) = subsets(a) + (subsets(a)包括b)

    = { [], [a] } + { [b], [a,b] } = { [], [a], [b], [a,b] }

    取c,子集(a,b,c) = 子集(a,b) + (子集(a,b)包括c)

    = {[], [a],[b],[a,b]} + {[c], [a,c], [b,c], [a,b,c]}

    获得所有子集后,打印总和等于目标的子集。如果不需要任何子集,可以进一步修改上述算法。

    【讨论】:

      【解决方案2】:

      以下是 javascript 中的答案:

      function subsetsum(A, target) {
      
      //int N = sizeof(A)/sizeof(int), sum = 0;
      var N = A.length, sum = 0;
      
      //for(int i = 0; i < N; i++) sum += A[i];
      for(var i = 0; i < N; i++) sum += A[i];
      
      // vector<bool> V(sum + 1, 0);
      var V = [];
      
      V[0] = [];
      for(var i = 0; i < N; i++) {
          for(var j = sum; j >= 0; j--) {
              if(j + A[i] <= sum && V[j]) {
                  //Join the subset of the memoized result to this result.
                  V[A[i] + j] = [A[i]].concat(V[j]);  
              } 
          }
      }
      console.log(V);
      //evaluates to true if V[target] exists
      return !!V[target];
      }
      

      【讨论】:

        【解决方案3】:

        查找vector&lt;int&gt;的幂集的函数

        vector<vector<int>> power_set(const vector<int>& nums) {
          if (nums.empty()) { return { {} }; }
          auto set = power_set(vector<int>(begin(nums) +1, end(nums)));
          auto tmp = set;
          for (auto& p : tmp) {
            p.push_back(nums[0]);
          }
          set.insert(end(set), begin(tmp), end(tmp));
          return set;
        }
        

        返回幂集中所有集合的函数

        vector<vector<int>> test_sum(const vector<vector<int>>& ps, int target) {
          vector<vector<int>> v;
          for (auto& p : ps) {
            int sum = accumulate(begin(p), end(p), 0);
            if (sum == target) {
              v.push_back(p);
            }
          }
          return v;
        }
        

        【讨论】:

          【解决方案4】:

          我修改了你的代码来打印数字。

          void subsetsum(int A[], int target) {
          
              int N = sizeof(A) / sizeof(int), sum = 0;
          
              for (int i = 0; i < N; i++) sum += A[i];
          
              vector<bool> V(sum + 1, 0);
              V[0] = 1;
              for (int i = 0; i < N; i++)
                  for (int j = sum; j >= 0; j--) {
                      if (j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
                  }
              if (V[target]) cout << "Sumbset sum exists" << endl;
              else cout << "Sumbset sum doesnt exist" << endl;
          
              if (V[target])
              {
                  for (int i = N - 1; i >= 0; i--)
                  {
                      if (V[target - A[i]] == 1) printf("%d, ", A[i]), target -= A[i];
                  }
                  printf("\n");
              }
          }
          

          或者这是我的矢量版本

          bool subsetsum_dp(vector<int>& v, int sum)
          {
              int n = v.size();
              const int MAX_ELEMENT = 100;
              const int MAX_ELEMENT_VALUE = 1000;
              static int dp[MAX_ELEMENT*MAX_ELEMENT_VALUE + 1]; memset(dp, 0, sizeof(dp));
          
              dp[0] = 1;
          
              for (int i = 0; i < n; i++)
              {
                  for (int j = MAX_ELEMENT*MAX_ELEMENT_VALUE; j >= 0; j--)
                  {
                      if (j - v[i] < 0) continue;
                      if (dp[j - v[i]]) dp[j] = 1;
                  }
              }
              if (dp[sum])
              {
                  for (int i = n - 1; i >= 0; i--)
                  {
                      if (dp[sum - v[i]] == 1) printf("%d, ", v[i]), sum -= v[i];
                  }
                  printf("\n");
              }
          
              return dp[sum] ? true : false;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多