您的位置:首页 > 其它

01背包(打印路径) 之 uva 624

2014-07-21 10:26 204 查看
//  [7/21/2014 Sjm]
/*
此题直接根据01背包的求解思路,记录路径,再递归输出。。1A。。
注:
对于最后一个测试用例 43 2 也是满足题目要求的,输出它也是对的。
*/


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAX_NUM = 25;
const int MAX_N = 100005;
struct node {
int t_n; // 得到它前面那个所取节点的位置
bool Judge;  // 判断当前节点是否被选择
};
int N, num;
int dp[MAX_NUM][MAX_N], arr[MAX_NUM];
node vis[MAX_NUM][MAX_N];

void output(int mynum, int myN, int sum) {
if (sum == 0) {
return;
}
if (vis[mynum][myN].Judge) {
output(mynum - 1, vis[mynum][myN].t_n, sum - arr[mynum]);
printf("%d ", arr[mynum]);
}
else {
output(mynum - 1, myN, sum);
}
}

void Solve() {
for (int i = 1; i <= num; ++i) {
for (int k = 0; k < arr[i]; ++k) {
dp[i][k] = dp[i - 1][k];
}
for (int j = arr[i]; j <= N; ++j) {
if (dp[i - 1][j - arr[i]] + arr[i] > dp[i - 1][j]) {
dp[i][j] = dp[i - 1][j - arr[i]] + arr[i];
vis[i][j].Judge = true;
vis[i][j].t_n = j - arr[i];
}
else { dp[i][j] = dp[i - 1][j]; }
}
}

int start;
for (start = num; start >= 0; --start) {
if (vis[start]
.Judge) {
break;
}
}
output(start, N, dp[start]
);

printf("sum:%d\n", dp[num]
);
}

int main()
{
//freopen("input.txt", "r", stdin);
while (~scanf("%d %d", &N, &num)) {
for (int i = 0; i <= num; ++i) {
for (int j = 0; j <= N; ++j) {
dp[i][j] = 0;
vis[i][j].Judge = false;
vis[i][j].t_n = -1;
}
}
for (int i = 1; i <= num; ++i) {
scanf("%d", &arr[i]);
}
Solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: