01背包问题需要找出相应路径

给定一个时间上限和n个cd盘,每个cd有一个播放时间,要求出不超过时间上限的情况下最多的可以播放的时间以及使用的cd。难点在于,如何保存路径。 例如输入:世界上限为5,一共有3个CD,每个CD播放时间分别:1分钟、3分钟、4分钟 输出:最多可以播放的时间是第一个CD和第三个CD,播放时间为五分钟。 分析如下: 图片1   图片2   图片3   图片4
#include 
#include 
#include 
using namespace std;

int sum, n, cd[25], i, j, k, dp[1111], out[1111][25], outn[1111];

//outn[i] 记录达到i值时用的元素个数
//out[i][0]~out[i][outn[j]] 记录达到i值时用的元素

int main() {
	while (~scanf("%d", &sum)) {
		scanf("%d", &n);
		memset(dp, 0, sizeof(dp));
		memset(out, 0, sizeof(out));
		memset(outn, 0, sizeof(outn));
		dp[0] = 1;
		for (i = 0; i < n; i ++)
			scanf("%d", &cd[i]);
		for (i = 0; i < n; i ++)
			for (j = sum; j >= cd[i]; j --)
				if (dp[j - cd[i]] && !dp[j]) {      //存在一个或几个数字组成j-cd[i]值 !dp[j]是指去掉重复的
					dp[j] = 1;                      //存在一个或几个数字组成j值
					for (k = 0; k < outn[j - cd[i]]; k ++)  {    //把组成j-cd[i]值的元素,复制得到j值所在的行
						out[j][outn[j]] = out[j - cd[i]][k];
						outn[j]++ ;
					}
					out[j][outn[j]++] = cd[i];    // 最后把元素cd[i]放到最后
				}
		for (i = sum; i >= 0; i --) {
			if (dp[i]) {
				sort(out[i], out[i] + outn[i]);
				for (j = 0; j < outn[i]; j ++) {
					printf("%d ", out[i][j]);
				}
				printf("sum:%d
", i);
				break;
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/NYNU-ACM/p/4236866.html