1. 程式人生 > >子集和問題使用dfs解決

子集和問題使用dfs解決

問題:就是給你一個數組m,和一個值n;

判斷在這個陣列中是否存在幾個數相加使得他們的和為n;

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n,m;
int vis[maxn];
int a[maxn];
int b[maxn];
int dfs(int sum, int k){
	if(sum > m)return 0;
	if(sum == m){
		for(int i = 0; i< k-1; i++){
			cout << b[i] << " ";
		}cout << b[k-1] << endl;
		return 1;
	}
	for(int i = 0; i < n; i++){
		if(!vis[i]){
			vis[i] = 1;
			b[k] = a[i];
			if(dfs(sum+a[i],k+1))
			return 1;
			vis[i] = 0;
		}
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin >> n >> m;
	int sum = 0;
	for(int i = 0; i < n; i++){
		cin >> a[i];
		sum += a[i];
	}
	if(sum < m)cout << "NO" << endl;
	else{
		if(dfs(0,0) == 0)cout << "NO" << endl;
	}
	
	return 0;
}

判斷是否存在:

程式碼如下:

int n, m;
int a[maxn];
bool dfs(int sum , int k){
	if(k == n)return sum == m;
	if(dfs(sum, k+1))return true;
	if(dfs(sum+a[k], k+1))return true;
	return false;
}

int main(){
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i =0; i<n; i++){
		cin >> a[i];
	}
	if(dfs(0,0)) cout << "YES" << endl;
	else cout << "NO" << endl;
	return 0;
}