开始以为用递归或者动态规划做,看了答案,发现是背包问题……
看了好久!!什么乱七八糟的!
#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][maxn], 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--)//从价值高的来!!
{
//状态转移方程,发现序号小的替代品
if (dp[v] <= dp[v - w[i]] + w[i])//等于时也要放
{
dp[v] = dp[v - w[i]] + w[i];
choice[i][v] = 1;//放入第i件物品
}
else choice[i][v] = 0;//不放第i件物品
}
}
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;
}
找路径那里写的比较复杂,可以自己优化一下。