1
+ use crate :: q:: Solution ;
2
+
3
+ #[ allow( unused) ]
4
+ impl Solution {
5
+ pub fn get_money_amount ( n : i32 ) -> i32 {
6
+ // 方法1
7
+ // 这道题的重点在于:我们不知道庄家会选哪个数字
8
+ // 所以我们必须假设,我们猜任何数字,庄家都会让我们去到最坏的情况
9
+ // 那么,在1..n之间,假设我们猜的数字是k,
10
+ // 这个时候,1..n会被分成了 1..k-1 k k + 1..n-1 3个部分
11
+ // 我们把k的左右部分分别叫lower和higher吧,
12
+ // 这里,如果k是答案,那就没问题
13
+ // 如果在lower或者higher,那么我们就又要去选一个数字,也就是再做一次
14
+ // 这是不是就是Divide And Conquer的感觉了
15
+ // 那么递归是肯定需要的了,所以我们其实是要pay的就是k + max(rec(lower), rec(higher))
16
+ // 这个值呢,对于我们自己来说,我们肯定想要的是最小的,这样我们可以pay最少,
17
+ // 所以,我们如果发现了下面的那个情况比之前已经做过的情况还要大的,那我们就减枝
18
+ // 最后留下的,就是最坏打算下的最少的pay
19
+ // 这里可能会有超时的可能,所以我们需要一个mem来记录一下
20
+ // AC 44ms 2.2mb 27/27
21
+ fn dac ( lo : usize , hi : usize , memo : & mut Vec < Vec < usize > > ) -> usize {
22
+ if lo >= hi { return 0 ; }
23
+ if memo[ lo] [ hi] > 0 { return memo[ lo] [ hi] ; }
24
+ let mut ans = usize:: MAX ;
25
+ for k in lo..=hi {
26
+ let cur = k + dac ( lo, k - 1 , memo) . max ( dac ( k + 1 , hi, memo) ) ;
27
+ ans = ans. min ( cur) ;
28
+ }
29
+ memo[ lo] [ hi] = ans;
30
+ return ans;
31
+ }
32
+ let n = n as usize ;
33
+ dac ( 1 , n, & mut vec ! [ vec![ 0 ; n + 1 ] ; n + 1 ] ) as i32
34
+ }
35
+ }
0 commit comments