@@ -4,42 +4,59 @@ struct Solution;
4
4
5
5
//problem 312
6
6
use std:: collections:: HashMap ;
7
- impl Solution {
8
- pub fn max_coins ( nums : Vec < i32 > ) -> i32 {
9
- if nums. is_empty ( ) {
10
- return 0 ;
7
+ use std:: iter:: FromIterator ;
8
+
9
+ struct Balloons < ' a > {
10
+ nums : & ' a [ i32 ] ,
11
+ remaining : Vec < usize >
12
+ }
13
+ impl < ' a > Balloons < ' a > {
14
+ fn new ( nums : & ' a [ i32 ] ) -> Self {
15
+ Self {
16
+ nums,
17
+ remaining : Vec :: from_iter ( 0 ..nums. len ( ) ) ,
11
18
}
12
- let mut dp = HashMap :: new ( ) ;
13
- Solution :: max_coins_recurse ( & nums, & mut dp)
14
19
}
15
20
16
- fn max_coins_recurse ( nums : & [ i32 ] , dp : & mut HashMap < Vec < i32 > , i32 > ) -> i32 {
17
- match nums. len ( ) {
18
- 1 => nums[ 0 ] ,
19
- 2 => nums[ 0 ] * nums[ 1 ] + nums[ 0 ] . max ( nums[ 1 ] ) ,
20
- _ => {
21
- let mut max = 0 ;
22
- for i in 0 ..nums. len ( ) {
23
- let slice = [ & nums[ 0 ..i] , & nums[ i + 1 ..] ] . concat ( ) as Vec < i32 > ;
21
+ fn pop ( & self , i : usize ) -> ( Self , i32 ) {
22
+ let mut remaining = self . remaining . clone ( ) ;
23
+ let i = remaining. remove ( i) ;
24
+ let left = remaining. iter ( ) . filter ( |v| * * v < i) . max ( ) . map ( |l| self . nums [ * l] ) . unwrap_or ( 1 ) ;
25
+ let right = remaining. iter ( ) . filter ( |v| * * v > i) . min ( ) . map ( |l| self . nums [ * l] ) . unwrap_or ( 1 ) ;
24
26
25
- let mut score = 1 ;
26
- if i != 0 {
27
- score *= nums[ i - 1 ] ;
28
- }
29
- score *= nums[ i] ;
30
- if i != ( nums. len ( ) - 1 ) {
31
- score *= nums[ i + 1 ] ;
32
- }
27
+ ( Self {
28
+ nums : self . nums ,
29
+ remaining
30
+ } ,
31
+ left * self . nums [ i] * right
32
+ )
33
+ }
34
+
35
+ fn score ( & self ) -> i32 {
36
+ self . score_recurse ( & mut HashMap :: new ( ) )
37
+ }
33
38
34
- if dp. contains_key ( & slice) {
35
- score += dp[ & slice] ;
39
+ fn score_recurse ( & self , dp : & mut HashMap < Vec < i32 > , i32 > ) -> i32 {
40
+ match self . remaining . len ( ) {
41
+ 0 => 0 ,
42
+ 1 => self . nums [ self . remaining [ 0 ] ] ,
43
+ 2 => self . nums [ self . remaining [ 0 ] ] * self . nums [ self . remaining [ 1 ] ]
44
+ + self . nums [ self . remaining [ 0 ] ] . max ( self . nums [ self . remaining [ 1 ] ] ) ,
45
+ _ => {
46
+ let mut max = 0 ;
47
+ for i in 0 ..self . remaining . len ( ) {
48
+ let ( new_b, mut score) = self . pop ( i) ;
49
+ let rem: Vec < i32 > = new_b. remaining . iter ( ) . map ( |i| self . nums [ * i] ) . collect ( ) ;
50
+ if dp. contains_key ( & rem) {
51
+ score += dp[ & rem] ;
36
52
} else {
37
- let sub_score = Solution :: max_coins_recurse ( & slice , dp) ;
38
- dp. insert ( slice , sub_score) ;
53
+ let sub_score = new_b . score_recurse ( dp) ;
54
+ dp. insert ( rem , sub_score) ;
39
55
score += sub_score;
40
56
}
57
+
41
58
if score > max {
42
- max = score;
59
+ max = score
43
60
}
44
61
}
45
62
max
@@ -48,16 +65,28 @@ impl Solution {
48
65
}
49
66
}
50
67
68
+ impl Solution {
69
+ pub fn max_coins ( nums : Vec < i32 > ) -> i32 {
70
+ Balloons :: new ( & nums) . score ( )
71
+ }
72
+ }
73
+
51
74
#[ cfg( test) ]
52
75
mod tests {
53
76
use crate :: dailies:: d20_12_13:: Solution ;
54
77
use std:: collections:: HashMap ;
55
78
56
79
#[ test]
57
80
fn it_works ( ) {
81
+ //36s
58
82
let foo = Solution :: max_coins ( vec ! [ 8 , 3 , 4 , 3 , 5 , 0 , 5 , 6 , 6 , 2 , 8 , 5 , 6 , 2 , 3 , 8 , 3 , 5 , 1 , 0 , 2 ] ) ;
59
83
}
60
84
85
+ #[ test]
86
+ fn long ( ) {
87
+ assert_eq ! ( Solution :: max_coins( vec![ 5 , 7 , 8 , 1 ] ) , 336 ) ;
88
+ }
89
+
61
90
#[ test]
62
91
fn test_map_array ( ) {
63
92
let mut map: HashMap < Vec < i32 > , bool > = HashMap :: new ( ) ;
0 commit comments