原题解释
链接:
UVa 624
题目分析:这道题是基础的0-1背包问题,体积和价值是一样的。难点在于要打印路径。
源代码
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
const int MAX = 10000;
int dp[MAX];
int v[MAX];
int w[MAX];
bool vis[22][MAX]; // track最多有20个,vis用于记录此步track有没有加进来
int max(int a, int b) { return (a > b) ? a : b;}
int main(int argc, char const *argv[])
{
//freopen("in.txt", "r", stdin);
int N, t;
while(cin >> N)
{
cin >> t;
for(int i = 1; i <= t; ++ i)
{
cin >> v[i];
w[i] = v[i]; // 体积v和重量w是一样的,实际上这句话没啥用
}
for(int j = 0; j <= N; ++ j)
dp[j] = 0; // 初始化
memset(vis, false, sizeof(vis));
for(int i = 1; i <= t; ++ i)
{
for(int j = N; j >= v[i]; -- j)
{
int ans = dp[j - v[i]] + w[i];
dp[j] = max(dp[j], ans);
if (dp[j] == ans) {
vis[i][j] = true; // 说明 i 加进来了
}
}
}
stack<int> s; // 结果是倒着的,所以用栈先保存一下
int j = N;
for(int i = t; i >= 0; -- i) {
if(vis[i][j]) {
s.push(v[i]);
j = j - v[i];
}
}
while(!s.empty()) {
cout << s.top() << " ";
s.pop();
}
cout << "sum:" << dp[N] << endl;
}
return 0;
}