价值和重量相等的特殊背包。所以求法还是0/1背包的求解过程,还是需要输出长度,所以用path[i][j]记录 i ( 从后往前记录 ) 然后递推输出即可。
// File Name: UVa624.cpp
// Author: Toy
// Created Time: 2013年04月16日 星期二 18时55分04秒
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cctype>
#include <cmath>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <utility>
#include <bitset>
#define L(x) x << 1
#define R(x) x << 1 | 1
using namespace std;
int Case, num, A[25], dp[10005];
bool path[25][10005];
int main ( ) {
while ( scanf ( "%d%d", &Case, &num ) != EOF ) {
for ( int i = 1; i <= num; ++i )
scanf ( "%d", &A[i] );
memset ( dp, 0, sizeof ( dp ) );
memset ( path, 0 ,sizeof ( path ) );
for ( int i = num; i >= 0; --i )
for ( int j = Case; j >= A[i]; --j ) {
if ( dp[j] < dp[j - A[i]] + A[i] ) {
dp[j] = dp[j - A[i]] + A[i];
path[i][j] = 1;
}
}
for ( int i = 1, j = Case; i <= num; ++i )
if ( path[i][j] ) printf ( "%d ", A[i] ), j -= A[i];
printf ( "sum:%d\n", dp[Case] );
}
return 0;
}