动态规划法设计求解子集和问题的算法,并分析算法时间和空间复杂度。
子集和问题:给定有n个不同正整数的集合A={a1, a2, …, an}和一个整数W,要求找出A的一个子集S,使得S中的所有元素之和为W.
// 算法.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include<stack>
#include <iostream>
// A Dynamic Programming solution for subset sum problem
using namespace std;
// Returns true if there is a subset of set[] with sun equal to given sum
bool isSubsetSum(int set[], int n, int sum) {
// The value of subset[i][j] will be true if there is a subset of set[0..j-1]
// with sum equal to i
bool** subset=new bool*[sum+1]; // boolean subset[][] = new boolean[sum + 1][n + 1];
for (int i = 0;i < sum + 1;i++) {
subset[i] = new bool[n + 1];
}
// If sum is 0, then answer is true
for (int i = 0; i <= n; i++)
subset[0][i] = true;
// If sum is not 0 and set is empty, then answer is false
for (int i = 1; i <= sum; i++)
subset[i][0] = false;
// Fill the subset table in botton up manner
for (int i = 1; i <= sum; i++)
{
for (int j = 1; j <= n; j++)
{
//
subset[i][j] = subset[i][j - 1];
if (i >= set[j - 1])
subset[i][j] = subset[i][j] || subset[i - set[j - 1]][j - 1];
}
}
/* output the point*/
stack<int>qsort;
int i = sum,j=n;
while (j>0&&i>0)
{
if (i < set[j - 1])
{
j--;
}
else if (subset[i][j] == true && subset[i - set[j - 1]][j - 1] == true)//find the point
{
qsort.push(j-1);
i = i - set[j - 1];
j--;
}
else
{
j--;
}
}
int length =int(qsort.size());
for (int i = 0; i <length; i++)
{
int cur = qsort.top();
qsort.pop();
cout << set[cur] << " ";
}
return subset[sum][n];
}
// Driver program to test above function
/*int main()
{
int set[] = { 3, 34, 4, 12, 5, 2 };
int sum = 9;
int n = sizeof(set) / sizeof(set[0]);
if (isSubsetSum(set, n, sum) == true)
cout << "Found a subset with given sum" << endl;
else
cout << "No subset with given sum" << endl;
return 0;
}*/