Facebook: User Bin Crash | Lucky's Notes
You're on a plane, and somehow you have to dump some cargo or else it will crash. You know how much you need to dump (in pounds), and also an inventory of the items you can dump.
Each item in the inventory has a certain weight, and a certain value. By dumping a combination of the items, you have to dump at minimum the given weight, while minimizing the loss.
You can only dump integral amounts of an item (you can't dump three quarters of a package), but you're allowed to dump any amount of the item.
The program you write takes the parameters and outputs the minimum loss (value of items that are dumped).
Read full article from Facebook: User Bin Crash | Lucky's Notes
You're on a plane, and somehow you have to dump some cargo or else it will crash. You know how much you need to dump (in pounds), and also an inventory of the items you can dump.
Each item in the inventory has a certain weight, and a certain value. By dumping a combination of the items, you have to dump at minimum the given weight, while minimizing the loss.
You can only dump integral amounts of an item (you can't dump three quarters of a package), but you're allowed to dump any amount of the item.
The program you write takes the parameters and outputs the minimum loss (value of items that are dumped).
However there’s something we can do about it. We can divide all weights by a common factor, and the result would be the same. In the example we can simply divide 13000000, 5000000, and 3000000 all by a million.
Needless to say, this would fail badly if W had been, for instance, 13000001.
public
static
void
main(String[] args)
throws
Exception{
BufferedReader in =
new
BufferedReader(
new
FileReader(args[
0
]));
// Minimum weight to prevent crash
int
crashw = Integer.parseInt(in.readLine());
// List containing weights of items
List<Integer> itemW =
new
ArrayList<Integer>();
// List containing values of items
List<Integer> itemV =
new
ArrayList<Integer>();
String parse;
while
( (parse = in.readLine()) !=
null
){
Scanner scn =
new
Scanner(parse);
scn.next();
itemW.add(scn.nextInt());
itemV.add(scn.nextInt());
}
// Take the GCD's before starting the DP
int
gcd = crashw;
for
(
int
i : itemW) gcd = gcd(gcd, i);
// Divide all weights by gcd
crashw /= gcd;
for
(
int
i=
0
; i<itemW.size(); i++)
itemW.set(i, itemW.get(i)/gcd);
// Calculate optimal fit using dynamic programming
int
[][] dp =
new
int
[itemW.size()][crashw+
1
];
// First row of DP array done separately
dp[
0
][
0
] =
0
;
for
(
int
j=
1
; j<=crashw; j++){
int
aW = itemW.get(
0
);
int
aV = itemV.get(
0
);
if
(aW > j) dp[
0
][j] = aV;
else
dp[
0
][j] = aV + dp[
0
][j-aW];
}
// Filling up the rest of the DP array
for
(
int
i=
1
; i<dp.length; i++){
dp[i][
0
] =
0
;
for
(
int
j=
1
; j<=crashw; j++){
int
iW = itemW.get(i);
int
iV = itemV.get(i);
// Cell directly up from current
int
imUp = dp[i-
1
][j];
// Cell left of it by iW
int
imLeft =
0
;
if
(iW > j) imLeft = iV;
else
imLeft = iV + dp[i][j-iW];
// Smallest of the two
dp[i][j] = imUp<imLeft? imUp: imLeft;
}
}
System.out.println(dp[itemW.size()-
1
][crashw]);
}
// GCD using the Euclid algorithm
static
int
gcd(
int
a,
int
b){
if
(b ==
0
)
return
a;
return
gcd(b, a%b);
}