【题目:https://www.patest.cn/contests/pat-a-practise/1068】
/**********************3stone****************************
FileName: PAT.1068.Find More Coins(30)
Author:3stone
Time:2017/3/2
题意:0-1背包问题; 多个答案时,输出最小序列
花费和价值等价,统一用一个数组表示
***********************3stone***************************/
#include<cstdio>
#include<algorithm>
using namespace std;
int coin[10010];
int dp[110] = { 0 };//边界
bool flag[10010];
bool choice[10010][110];
bool cmp(int a, int b){
return a > b;
}
int main(){
int n, m;
while(scanf("%d%d", &n, &m) != EOF){
for(int i = 1; i <= n; i++){
scanf("%d", &coin[i]);
}
sort(coin + 1, coin + n + 1, cmp);//逆序排列
for(int i = 1; i <= n; i++){
for(int j = m; j >= coin[i]; j--){
if(dp[j] > dp[j - coin[i]] + coin[i]){
choice[i][j] = 0;
}
else{
dp[j] = dp[j - coin[i]] + coin[i];
choice[i][j] = 1;
}
}
}
if(dp[m] != m) printf("No Solution\n");
else{//输出方案
int k = n, num = 0, v = m;
while(k >= 0){
if(choice[k][v] == 1){
flag[k] = true;
v -= coin[k];
num++;
}
else
flag[k] = false;
k--;
}
for(int i = n; i >= 1; i--){
if(flag[i] == true){
printf("%d", coin[i]);
num --;
if(num > 0) printf(" ");
}
}
}//else-输出方案
}//while
return 0;
}