[每日N题] 4.1 UVA - 242 [背包问题]

Stamps and Envelope Size UVA - 242

状态转移方程:
d[i][k] = max(max(d[i-1][k], d[i][k]), d[i-1][k-sortP[j]]+sortP[j]);
本来以为会超时,但是幸好没有超时,不过也就差一点了

我的代码:

#include<cstdio> 
#include<algorithm>
#include<cstring>
#include<functional>

using namespace std;

const int MAXN = 100;

int maxCoverage = -1, ansLen = -1, ans[MAXN], sortAns[MAXN];
int d[12][MAXN*MAXN+10], p[MAXN], sortP[MAXN], S, N, len;

bool init () {
	scanf("%d", &S);
	if (S == 0) return false;
	scanf("%d", &N);
	maxCoverage = 0;
	ansLen = 0;
	return true;
}

void read () {
	scanf("%d", &len);
	for (int i = 0; i < len; i++) {
		scanf("%d", &p[i]);
	}
	memcpy(sortP, p, sizeof(p));
	sort(sortP, sortP+len, greater<int>());
	memset(d, 0, sizeof(d));
}

void dp () {
	for (int i = 1; i <= S; i++) {
		for (int j = 0; j < len; j++) {
			for (int k = 10000; k >= 0; k--) {
				if (k >= sortP[j]) {
					d[i][k] = max(max(d[i-1][k], d[i][k]), d[i-1][k-sortP[j]]+sortP[j]);
				} else {
					d[i][k] = max(d[i-1][k], d[i][k]);
				}
			}
		}
	}
}

bool better () {
	int coverage = -1;
	for (int i = 0; ; i++) {
		if (d[S][i] != i) {
			coverage = i-1;
			break;
		}
	}
	if (coverage < maxCoverage || (coverage == maxCoverage && len > ansLen)) return false;
	if (coverage == maxCoverage && len == ansLen) {
		for (int i = 0; i < len; i++) {
			if (sortAns[i] < sortP[i]) return false;
			if (sortAns[i] > sortP[i]) break;
		}
	}
	maxCoverage = coverage;
	return true;
}

int main () {
	while (init()) {
		for (int n = 0; n < N; n++) {
			read();
			dp();
			if (better()) {
				memcpy(ans, p, sizeof(p));
				memcpy(sortAns, sortP, sizeof(sortP));
				ansLen = len;
			}
		}
		printf("max coverage =%4d :", maxCoverage);
		for (int i = 0; i < ansLen; i++) {
			printf("%3d", ans[i]);
		}
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/AdamAndTina/article/details/88945216
242