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;
}