TYVJ 1086 Elevator 解题报告
我不写结题报告吧,贴别人的,还是抱怨一下,题目没说清楚,说"且第i种箱子不能放在高度超过A_i的地方。"是箱顶不能超过而不是箱底不能超过,怪不得我的那个不能AC:
先按照A_i 排序,最好用快速排序
然后再按01背包枚举
关键代码:
===========================================
qsort(1,n);
f[0]:=true;
for i:=1 to n do
for j:=1 to c[i] do
for k:=a[i] downto h[i] do
if f[k-h[i]] then f[k]:=true;
===========================================
然后找出最大的x使得f[x]=true 输出X即可
===========================================
写下体会吧,碰到这种把几个东西放在一起的题目就要用这种填充的方式了,但是要注意的是高度是从高到低循环,不然的话就类似于无限背包了,嗯,有点体会吧,这种题目。
我的代码:
#include <stdio.h> #include <stdlib.h> #define min(a, b) ((a)<(b)?(a):(b)) struct box{ int h, a, c; }box[400]; int f[40101]; int ans; int com(const void *a, const void *b) { struct box *i = (struct box *)a, *j = (struct box *)b; return i->a - j->a; } int main(int argc, char **argv) { int i, j, k; int n; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d%d%d", &box[i].h, &box[i].a, &box[i].c); } qsort(box, n, sizeof(struct box), com); f[0] = 1; for(i = 0; i < n; i++){ for(j = 1; j <= box[i].c; j++){ for(k = min(box[i].a - box[i].h, ans); k >= 0; k--){ if(f[k]){ if(ans < k + box[i].h){ ans = k + box[i].h; } f[k + box[i].h] = 1; } } } } printf("%d\n", ans); return 0; }