1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
pub mod recursion {
use std::cmp::max;
pub fn f(n: usize) -> usize {
if n <= 2 {
return n;
}
max(f(n - 1) + 1, g(n, 1))
}
fn g(n: usize, j: usize) -> usize {
if j > n - 3 {
return n - j;
}
max(g(n, j + 1), f(n - j - 2) * (j + 1))
}
pub use f as solve;
}
pub mod dp {
use std::cmp::max;
pub fn solve(n: usize) -> usize {
let mut dpt = vec![0; n + 1];
if n >= 1 {
dpt[1] = 1;
}
if n >= 2 {
dpt[2] = 2;
}
if n >= 3 {
dpt[3] = 3;
}
if n >= 4 {
for i in 4..=n {
let v1 = dpt[i - 1] + 1;
let v2 = {
let mut prev = 2usize;
for j in (1..=(i - 3)).rev() {
prev = max(prev, dpt[i - j - 2] * (j + 1));
}
prev
};
dpt[i] = max(v1, v2);
}
}
dpt[n]
}
}
#[cfg(test)]
mod tests {
#[test]
fn problem_0651() {
for solve in [
super::recursion::solve,
super::dp::solve,
] {
assert_eq!(solve(0), 0);
assert_eq!(solve(1), 1);
assert_eq!(solve(2), 2);
assert_eq!(solve(3), 3);
assert_eq!(solve(4), 4);
assert_eq!(solve(5), 5);
assert_eq!(solve(6), 6);
assert_eq!(solve(7), 9);
assert_eq!(solve(8), 12);
assert_eq!(solve(9), 16);
assert_eq!(solve(10), 20);
assert_eq!(solve(11), 27);
assert_eq!(solve(12), 36);
assert_eq!(solve(13), 48);
assert_eq!(solve(14), 64);
assert_eq!(solve(15), 81);
assert_eq!(solve(16), 108);
assert_eq!(solve(17), 144);
assert_eq!(solve(18), 192);
assert_eq!(solve(19), 256);
assert_eq!(solve(20), 324);
assert_eq!(solve(21), 432);
assert_eq!(solve(22), 576);
assert_eq!(solve(23), 768);
assert_eq!(solve(24), 1024);
assert_eq!(solve(25), 1296);
assert_eq!(solve(26), 1728);
assert_eq!(solve(27), 2304);
assert_eq!(solve(28), 3072);
assert_eq!(solve(29), 4096);
assert_eq!(solve(30), 5184);
}
}
}