一、题目描述
Input Specification:
Output Specification:
Sample Input 1:
8 9
5 9 8 7 2 3 4 1
Sample Output 1:
1 3 5
Sample Input 2:
4 8
7 2 4 3
Sample Output 2:
No Solution
二、解题思路
01背包问题,是动态规划问题,由于笔者对这方面的知识掌握得还不是很到位,建议大家去翻翻《算法笔记》中关于背包问题的讲述。
三、AC代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10010;
const int maxv = 110;
int w[maxn], dp[maxv] = {
0}; //w[i]为钱币的价值
bool choice[maxn][maxv], flag[maxn];
bool cmp(int a, int b)
{
return a > b; }//从大到小排序
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
sort(w + 1, w + n + 1, cmp); //逆序排列
for(int i = 1; i <= n; i++)
{
for(int v = m; v >= w[i]; v--)
{
dp[v] = max(dp[v], dp[v-w[i]]+w[i]); //状态转移方程
if(dp[v] == dp[v-w[i]]+w[i])
choice[i][v] = 1;
else
choice[i][v] = 0;
}
}
if(dp[m] != m) printf("No Solution"); //无解
else
{
//记录最优路径
int k = n, num = 0, v = m;
while(k >= 0)
{
if(choice[k][v] == 1)
{
flag[k] = true;
v -= w[k];
num++;
}
else flag[k] = false;
k--;
}
//输出方案
for(int i = n; i >= 1; i--)
{
if(flag[i] == true)
{
printf("%d", w[i]);
num--;
if(num > 0) printf(" ");
}
}
}
return 0;
}