版权声明:欢迎学习我的博客,希望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])传入参数了,那 不选第一个数 这个状态就被没有搜啊。。。