Skip to content

Commit c6d2e23

Browse files
committed
Solve #312
1 parent 0d4b3b6 commit c6d2e23

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,4 @@ mod n0306_additive_number;
232232
mod n0307_range_sum_query_mutable;
233233
mod n0309_best_time_to_buy_and_sell_stock_with_cooldown;
234234
mod n0310_minimum_height_trees;
235+
mod n0312_burst_balloons;

src/n0312_burst_balloons.rs

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* [312] Burst Balloons
3+
*
4+
* Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
5+
*
6+
* Find the maximum coins you can collect by bursting the balloons wisely.
7+
*
8+
* Note:
9+
*
10+
*
11+
* You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
12+
* 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
13+
*
14+
*
15+
* Example:
16+
*
17+
*
18+
* Input: [3,1,5,8]
19+
* Output: 167
20+
* Explanation: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
21+
* coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
22+
*
23+
*/
24+
pub struct Solution {}
25+
26+
// submission codes start here
27+
28+
/*
29+
The key idea is, for a sequence of balloon, select a balloon to be the last one to be bursted:
30+
31+
max of [1 . a b c d e f . 1]
32+
33+
^ say we select 'c' as the last balloon to burst, then:
34+
35+
=
36+
max of [1 . a b . c] +
37+
38+
max of [c . d e f . 1] +
39+
40+
1 * c * 1
41+
42+
Then we can use memorize to record the max of every sub sequence
43+
*/
44+
impl Solution {
45+
pub fn max_coins(nums: Vec<i32>) -> i32 {
46+
if nums.is_empty() {
47+
return 0
48+
}
49+
let mut coins = vec![0; nums.len()+2];
50+
let mut len = 0_usize;
51+
// filter out zeros
52+
for &num in nums.iter() {
53+
if num != 0 {
54+
len += 1;
55+
coins[len] = num;
56+
}
57+
}
58+
coins[0] = 1;
59+
coins[len+1] = 1;
60+
61+
let mut memo = vec![vec![0; len+1]; len+1];
62+
Solution::max_subrange(&coins, 1, len, &mut memo)
63+
}
64+
65+
fn max_subrange(coins: &Vec<i32>, start: usize, end: usize, memo: &mut Vec<Vec<i32>>) -> i32 {
66+
if memo[start][end] != 0 {
67+
return memo[start][end]
68+
}
69+
if start == end {
70+
memo[start][end] = coins[start-1] * coins[start] * coins[start+1];
71+
return memo[start][end]
72+
}
73+
let mut max = 0;
74+
for i in start..end+1 {
75+
let left_max = if i > start { Solution::max_subrange(coins, start, i-1, memo) } else { 0 };
76+
let right_max = if i < end { Solution::max_subrange(coins, i+1, end, memo) } else { 0 };
77+
max = i32::max(max, left_max + right_max + coins[i] * coins[start-1] * coins[end+1]);
78+
}
79+
memo[start][end] = max;
80+
return memo[start][end]
81+
}
82+
}
83+
84+
// submission codes end
85+
86+
#[cfg(test)]
87+
mod tests {
88+
use super::*;
89+
90+
#[test]
91+
fn test_312() {
92+
assert_eq!(Solution::max_coins(vec![3,1,5,8]), 167);
93+
}
94+
}

0 commit comments

Comments
 (0)