动态规划法设计求解子集和

动态规划法设计求解子集和问题的算法,并分析算法时间和空间复杂度。

子集和问题:给定有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;
}*/

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值