【51Nod - 1268】和为K的组合 (背包 或 dfs)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/83115964

题干:

给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K。如果可以,输出:"Yes",否则输出"No"。

Input

第1行:2个数N, K, N为数组的长度, K为需要判断的和(2 <= N <= 20,1 <= K <= 10^9) 
第2 - N + 1行:每行1个数,对应数组的元素Aii (1 <= Aii <= 10^6)

Output

如果可以,输出:"Yes",否则输出"No"。

Sample Input

5 13
2
4
6
8
10

Sample Output

No

解题报告:

    很多人说这题用背包,,,但是我一直想不通,1e9的空间,是怎么用的背包。。。这题数据量20,显然是搜索啊,,,复杂度o(2^n)不怂,不到30行就搞定了。

   如果要写背包的话思路上也是可以的,因为每个背包体积1e6,20个加起来也才2e8,并且dp[j]=val,这里可以保证jval<=j,因为物品的体积和价值是相同的啊。所以直接跑恰好装满问题,并且dp[k]=k就可以了。只要数组开的下,,背包也不难写。

扫描二维码关注公众号,回复: 3636087 查看本文章

AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k;
ll a[55];
bool dfs(ll step,ll cur) {
	if(cur  == k) return 1;
	if(step == n) return 0;
	if(cur+a[step+1] <= k) {
		if(dfs(step+1,cur+a[step+1])) return 1;
	}
	if(dfs(step+1,cur)) return 1;
	return 0;
}
int main()
{
	cin>>n>>k;
	for(int i = 1; i<=n; i++) cin>>a[i];
	sort(a+1,a+n+1); 
	if(dfs(0,0)) puts("Yes");
	else puts("No");
	return 0 ;
}

总结:搜索题一定要注意啊,需要从(0,0)这个状态开始搜索,因为你直接(1,a[1])传入参数了,那  不选第一个数 这个状态就被没有搜啊。。。

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/83115964