给出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
代码 1 01背包 虽然k很大但是 仔细看题就知道,所有元素加起来也不会超过 2*1e7 。 所以可以用01背包
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 20000005;
const int MAXM = 1e5;
int cost[100];
int dp[MAXN];
int main(){
int n,k;scanf("%d%d",&n,&k);
LL sum=0;
for(int i=1;i<=n;i++) {
scanf("%d",&cost[i]);
sum+=(LL) cost[i];
}
if(sum<k) puts("No");
else {
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
for(int j=k;j>=cost[i];j--)
dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]);
}
printf("%s\n",dp[k]==k?"Yes":"No");
}
return 0;
}
代码二 dfs 搜索 遍历所有情况,看是否符合
代码
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 20000005;
const int MAXM = 1e5;
int cost[100]={0};
int flag; //是否找到符合题意的情况
int n,k;
void dfs(int now,int sum){
if(flag) return;
if(sum==k) { flag=1; return ;}
if(sum>k) return ;
for(int i=now+1;i<=n;i++)
dfs(i,sum+cost[i]);
}
int main(){
scanf("%d%d",&n,&k);
LL sum=0;
for(int i=1;i<=n;i++) {
scanf("%d",&cost[i]);
sum+=(LL) cost[i];
}
if(sum<k) puts("No");
else {
flag=0;
dfs(0,0);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}