题目链接:http://115.159.40.116/problem_show.php?pid=5767
题目描述
有N种物品各一个,问是否能够凑成Mkg装到背包中。
输入
第一行一个整数T(T<=1000)测试数据组数,每组第一行为(1<N<=1000),M(1<m<=1000)两个正整数,第二行N个整数代表N种物品的质量Gi(小于1000)。
输出
可以凑成输出“Y”,否则输出“N”
样例输入
2 3 5 1 2 3 3 7 1 2 3
样例输出
Y N
<span style="font-size:18px;">#include<cstdio>
#include<cstring>
#include<iostream>
#define M 1000+10
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,s=0,dp[M],v[M];
memset(dp,0,sizeof(dp));
scanf("%d%d",&n, &m);
for(int i=0; i<n; ++i){
scanf("%d",&v[i]);
s+=v[i];
}
if(s==m) printf("Y\n");
else if(s<m) printf("N\n");
else{
for(int i=0; i<n; ++i){
for(int j=m; j>=v[i]; --j){ //保证能放下该物品
dp[j]=max(dp[j], dp[j-v[i]]+v[i]); /*确定的容量下,该物品放与不放 ,哪个能使容量最大 */
}
}
if(dp[m]==m) printf("Y\n");
else printf("N\n");
}
//printf("%d\n",dp[m]);
}
return 0;
}</span>
另一种解决方案(高效率),以当前点为起点,选择加还是不加,搜索:
<span style="font-size:12px;">#include <iostream>
#include<cstdio>
using namespace std;
int pack[1005],m;
bool ok;
void dfs(int i, int sum){
if(ok) return ;
if(i<1) return ;
if(sum==m){
ok=true;return;
}
if(sum>m) return;
dfs(i-1,sum+pack[i]);
dfs(i-1,sum);
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n, &m);
for(int i=1; i<=n; ++i){
scanf("%d",&pack[i]);
}
ok=false;
dfs(n,0);
if(ok)
printf("Y\n");
else
printf("N\n");
}
return 0;
}</span><span style="font-size: 24.5px;">
</span>