题目描述:
给定N个数字,从N个数字中选择任意k个数字,使之和等于M。
例如有5个数字:5 3 6 8 4 M=16
那么可以选择5 3 8使之和为16。
解题思路:
我们可以把M看做是一个背包,而给定的数字是价值和重量相等的物品,在容量一定的情况下,我们能选择的最大的价值一定是小于等于背包容量的,也就是<=m,如果最终 f[n][m]==m 说明能选出m的组合,当然也可以用一维01背包,但是如果要求具体组合是哪几个数组成了m,必须通过01背包的二维数组查找。
代码:
#include<iostream>
using namespace std;
int f[100][100];
int a[100];
int n,m;
int main(){
cin>>n>>m;
for (int i=1; i<=n; i++)
cin>>a[i];
for (int i=1; i<=n; i++){
for (int j=1; j<=m; j++){
if (j>=a[i]) f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+a[i]);
else f[i][j]=f[i-1][j];
}
}
for (int i=1; i<=n; i++){
for (int j=1; j<=m; j++)
cout<<f[i][j]<<" ";
cout<<endl;
}
if (f[n][m]==m) cout<<"yes"; else cout<<"no";
}