Programming Practice Midterm 7302013 UVA 10261 Ferry Loading Abridged Problem Statement There is a ferry that has two sides portstarboard Both sides are L unit long L lt10000 You are given a sequence of cars to be loaded onto the ferry Each car has an integer length in ID: 280485
Download Presentation The PPT/PDF document "Bowen Yu" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
Bowen YuProgramming Practice Midterm, 7/30/2013
UVA 10261 – Ferry Loading Slide2
Abridged Problem Statement
There is a ferry that has two sides (port/starboard). Both sides are
L
-unit long (
L<=10000). You are given a sequence of cars to be loaded onto the ferry. Each car has an integer length in [100, 10000]. You can decide to which side of the ferry each car is loaded. But you have to load them in the input order and stop as soon as one car cannot be loaded to either side. Task: Maximize the number of cars you can load, and print a way of loading maximum number of cars (any will do).
2Slide3
Sample Case
L
= 5000, Cars = {2500, 3000, 1000, 1000, 1500, 700, 800}
3
Answer:6port (2500)
starboard
(3000)
starboard
(1000)
starboard
(1000)
p
ort (1500)
p
ort (700)
Let’s verify:
p
ort = 2500 + 1500 + 700 = 4700 < 5000 (4700 + 800 > 5000)
s
tarboard = 3000 + 1000 + 1000 = 5000 (5000 + 800 > 5000)Slide4
First Step: Understand and formalize the task
You may forget about the ferry-car story and switch to a more straightforward model instead.
A simpler model:
You are given some objects one by one. Pack as many of them as you can into two equal-size containers, so that the volume sum of the objects in either container does not exceed the capacity of the container.
4Slide5
Second Step: Observe input magnitude
Values are all integers, i.e. discrete.
The size of the container is up to 10000.
The size of one object is [100, 10000].
Unfortunately, the number of objects is not given (at first glance there is no bound).Can we determine its range?
The container is at most 10000 large, and each object is at least 100, so we can pack at most 200 objects (don’t forget you have 2 containers!).
5
Small!
Small!
Good for memo!
YES!Slide6
Choice Step: Decide your approach
Enumerating decisions for 200 objects is clearly
TLE
. So forget about complete search.
There is no greedy strategy that makes sense. (Easy to show yourself some counterexamples)See that the input are integers, and limited in range (up to 10000). Also the objects are given in an order that we can not change (forward property).This recalls us directly to DP.
6Slide7
Design Step: Design your DP solution
To use DP, we need to first choose the states we will maintain.
Candidate 1:
memorize our decision for each object
Not feasible, that is 2NThink… How does our previous choices affect the current decision?Only the volume used matters!
We just need to know whether we can pack the previous objects into the two containers, so that we occupy
V
1
unit of space in container 1, and
V
2
unit of space in container 2
7Slide8
Design Step: Design your DP solution (cont’d)
Candidate 2:
memorize whether we can pack the previous objects (objects that appear before the
i
-th object we’re currently considering) so that the volume used are (V1, V2) respectively for the 2 containers. So the state is (
i
,
V
1
,
V
2
) = {true, false}.
Not feasible :(
This would require [200][10000][10000] for all the states, which is clearly
MLE
8Slide9
Design Step: Improve our DP!
We need to reduce the space requirement for our DP.
Think…
Can we drop one variable, and recover it from the others?
YES!Suppose we know a valid state (i, V1, V
2
).
Note that we also know the sum of volumes of objects we’ve already packed, say
V
sum
. Then,
V
2
=
V
sum
– V
1
.
9Slide10
Design Step: Improve our DP! (cont’d)
Candidate 3:
memorize whether we can pack the previous objects (before the
i
-th object we’re currently considering) so that the volume used are (V1, V2). But the state is (i
,
V
1
)
instead of (
i
,
V
1
,
V
2
) as we can recover
V
2 from V1
.This gives us [200][10000] states.This candidate
WORKS
within the
Memory Limit
!
:)
10Slide11
Design Step: Check the relations between DP states
Suppose a previously achievable state is (
i
,
V1, V2). (I write three parameters for clear explanation, though we do not store 3-parameter states physically)We are considering the i-
th
object of size
V
i
.
We have two choices with respect to this previously achievable state (
i
,
V
1
,
V
2
):
Put it into the first container (when
V
1+Vi <=
L
)
(
i
,
V
1
,
V
2
) -> (
i+1
,
V
1
+
V
i
,
V
2
)
2) Put it into the second container (when
V2+Vi <= L) (i, V1, V2) -> (i+1, V1, V2+Vi)
11Slide12
Design Step: Check the time complexity
First, for each object we have to enumerate the previously achievable states, which is O(
L
).
For each object, we need to consider two decisions, which is constant time.We have to do the above for each of the objects. We multiply the time by the number of objects. Therefore, we have finally an O(NL) time DP solution, where N<=200, L<=10000.
Now we know, this solution really
WORKS
, as both time and space requirements are satisfied.
12Slide13
Design Step: Be careful of the problem requirement
Don’t forget that the problem asks us to print the actual solution in addition to the maximum number of objects we can pack.
This is a DP solution memo requirement.
We can do it
without increasing our space requirement. When we reach a new state from a previous one, we can store a backward pointer of the new state to the previous state.In this way later we can trace back from the final state all the way to the initial state and figure out every decision, via the backward pointers.
Each state of DP has exactly one backward pointer, so the backward pointers together take the same space as the
dp
states.
13Slide14
Case Demo
14
L
= 5000, {2500, 3000, 1000, 1000, 1500, 700, 800}
0
0 (2500)
2500 (0)
3000 (2500)
2500 (3000)
4000 (2500)
3000 (3500)
3500 (3000)
2500 (4000)
4000 (3500)
3000 (4500)
3500 (4000)
2500 (5000)
4500 (3000)
5000 (2500)
i=0
i=2
3000
i=1
2500
i=3
1000
i=4
1000Slide15
Case Demo
15
L
= 5000, {2500, 3000, 1000, 1000, 1500, 700, 800}
4000 (3500)
3000 (4500)
3500 (4000)
2500 (5000)
4500 (3000)
5000 (2500)
i=4
1000
i=5
1500
4000 (5000)
4500 (4500)
5000 (4000)
4700 (5000)
5000 (4700)
i=6
700
i=7
800Slide16
Case Demo (Trace back the actual solution)
16
L
= 5000, {2500, 3000, 1000, 1000, 1500, 700, 800}
4000 (3500)
3000 (4500)
3500 (4000)
2500 (5000)
4500 (3000)
5000 (2500)
i=4
1000
i=5
1500
4000 (5000)
4500 (4500)
5000 (4000)
4700 (5000)
5000 (4700)
i=6
700
i=7
800
Container 2
Container 1Slide17
Case Demo (Trace back the actual solution)
17
L
= 5000, {2500, 3000, 1000, 1000, 1500, 700, 800}
0
0 (2500)
2500 (0)
3000 (2500)
2500 (3000)
4000 (2500)
3000 (3500)
3500 (3000)
2500 (4000)
4000 (3500)
3000 (4500)
3500 (4000)
2500 (5000)
4500 (3000)
5000 (2500)
i=0
i=2
3000
i=1
2500
i=3
1000
i=4
1000
Container 1
Container 2
Container 1
Container 1Slide18
Final Step: Code and submit!
Pay attention to the input format.
L
is given in meters, but lengths of cars are in centimeters. So we shall do an easy conversion.
As the number of cars is unknown beforehand, the input car length sequence of each case is terminated by 0. If one car cannot be loaded, all the following cars cannot be loaded either. But we still need to read in the other car lengths.
Allocate arrays with redundant entries, or be careful with off-by-one errors. Note that a minimum of
L
+1 entries is required for each DP table row.
18Slide19
Final Step: Code and submit! (cont’d)
Test
your code with predesigned test cases
.
For example:L = 1, {10000} Cannot load any car! output 0L = 1, {100, 100} One car at each side…Good thing about DP:
Usually if you have a clear thinking of your DP logic (time, space, state transition
,
etc.),
you have a high chance of getting
1A
(got
Accepted
using
1
submission).
Finally,
Submit and have fun!
:D
19Slide20
Sample Solutions
I’ve written one
C++
solution and one
Java solution for this problem, which will be given out with this slide.(In fact for this problem, you can use space saving trick if you like for the DP table, but not for the backward pointers.)
I’ve
added exhaustive comments
for each statement, and expand each variable to its full name (instead of contest-style short name) so as to minimize the chance you can confused.
Hope they help!
20Slide21
Thanks
21