動態規劃法設計求解子集和

動態規劃法設計求解子集和問題的算法,並分析算法時間和空間複雜度。

子集和問題:給定有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;
}*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章