UVa 946 - A Pile of Boxes

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

一個神祕的堆疊方式,假如燒杯大小大於要放入的燒杯,在不超過其原本的燒杯高度的情況下,則可以將其放入內部,放入內部後,可能掉入底層的燒杯中。

根據這樣的方式模擬最後堆疊的最大高度。

Sample Input

1
2
3
4
5
6
7
8
9
8
10
4
6
3
11
7
8
5

Sample Output

1
29

Solution

半夜爬起來寫的,總覺得檢查事件挺麻煩的事情,因此採用遞迴的方式建造,在退回的情況下查閱是否要疊在上方。

inner 表示內部底層的燒杯、outer 表示上方的燒杯,footer 表示下方的燒杯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int inner[105], outer[105], footer[105];
int height[105], A[105];
int place(int i, int mxI, int limit) {
// printf("down %d %d\n", A[mxI], mxI);
if(A[mxI] < A[i]) {
if(height[mxI] + A[i] <= limit) {
outer[mxI] = i, footer[i] = mxI;
height[i] = height[mxI] + A[i];
}
return height[mxI] + A[i];
}
if(inner[mxI] == -1) {
int h = place(i, footer[mxI], height[mxI] - A[mxI]);
if(h <= height[mxI] - A[mxI]) // complete
return h;
inner[mxI] = i, footer[i] = footer[mxI];
height[i] = height[mxI] - A[mxI] + A[i];
return height[i];
} else {
mxI = inner[mxI];
while(outer[mxI] != -1)
mxI = outer[mxI];
int h = place(i, mxI, height[mxI]);
if(h == height[mxI] - A[mxI] + A[i]) {
h = place(i, footer[mxI], height[mxI] - A[mxI]);
// printf("check %d %d\n", h, height[mxI] - A[mxI]);
if(h <= height[mxI] - A[mxI])
return h;
inner[mxI] = i, footer[i] = footer[mxI];
height[i] = height[mxI] - A[mxI] + A[i];
return height[i];
} else if(h > height[mxI]) {
if(height[mxI] + A[i] <= limit) {
outer[mxI] = i, footer[i] = mxI;
height[i] = height[mxI] + A[i];
}
return height[mxI] + A[i];
} else {
// puts("hello");
return h;
}
}
}
int main() {
int n;
while(scanf("%d", &n) == 1) {
for(int i = 0; i <= n; i++)
inner[i] = outer[i] = footer[i] = height[i] = -1;
A[0] = 0, height[0] = 0;
for(int i = 1; i <= n; i++)
scanf("%d", &A[i]);
int mxH = 0, mxI = 0;
for(int i = 1; i <= n; i++) {
int h = place(i, mxI, mxH);
if(h > mxH) {
outer[mxI] = i, footer[i] = mxI;
height[i] = height[mxI] + A[i];
}
h = height[i];
// printf("[%d] %d - %d mxH = %d mxI %d\n", i, A[i], h, mxH, mxI);
// for(int j = 1; j <= i; j++)
// printf("--------[%d] %2d * in %2d out %2d foot %2d\n", j, A[j], inner[j], outer[j], footer[j]);
if(h > mxH) mxH = h, mxI = i;
}
printf("%d\n", mxH);
}
return 0;
}