1#![feature(test)]
4
5extern crate test;
6
7struct Sol115;
9
10impl Sol115 {
11 pub fn num_distinct(s: String, t: String) -> i32 {
12 let mut rst = 0;
13 let (s, t) = (s.as_bytes(), t.as_bytes());
14 let mut mem = vec![vec![-1; t.len()]; s.len()];
15
16 fn count(s: &[u8], i: usize, j: usize, t: &[u8], mem: &mut Vec<Vec<i32>>) -> i32 {
17 if j + 1 >= t.len() {
18 return 1;
19 }
20 if i >= s.len() {
21 return 0;
22 }
23
24 if mem[i][j] != -1 {
25 return mem[i][j];
26 }
27
28 let mut rst = 0;
29 for p in i + 1..s.len() {
30 if s[p] == t[j + 1] && s.len() + j + 1 >= t.len() + p {
31 rst += count(s, p, j + 1, t, mem);
32 }
33 }
34 mem[i][j] = rst;
35 rst
36 }
37
38 for p in 0..s.len() {
39 if s[p] == t[0] && s.len() >= t.len() + p {
40 rst += count(s, p, 0, t, &mut mem);
41 }
42 }
43
44 println!("-> {:?}", mem);
45
46 rst
47 }
48}
49
50struct Sol132;
52
53impl Sol132 {
54 pub fn min_cut(s: String) -> i32 {
55 let s = s.as_bytes();
56
57 let mut palindrome = vec![vec![true; s.len()]; s.len()];
58 for l in (0..s.len()).rev() {
59 for r in l + 1..s.len() {
60 palindrome[l][r] = s[l] == s[r] && palindrome[l + 1][r - 1];
61 }
62 }
63
64 println!("-> {:?}", palindrome);
65
66 let mut dp = vec![i32::MAX; s.len()];
67 for r in 0..s.len() {
68 if palindrome[0][r] {
69 dp[r] = 0;
70 } else {
71 for l in 0..r {
72 if palindrome[l + 1][r] {
73 dp[r] = dp[r].min(dp[l] + 1);
74 }
75 }
76 }
77 }
78
79 dp[s.len() - 1]
80 }
81}
82
83struct Sol174;
85
86impl Sol174 {
87 pub fn calculate_minimum_hp(dungeon: Vec<Vec<i32>>) -> i32 {
88 let (rows, cols) = (dungeon.len(), dungeon[0].len());
89 let mut health = vec![vec![i32::MAX; cols + 1]; rows + 1];
90
91 health[rows][cols - 1] = 1;
92 health[rows - 1][cols] = 1;
93
94 for r in (0..rows).rev() {
95 for c in (0..cols).rev() {
96 let x = health[r + 1][c].min(health[r][c + 1]) - dungeon[r][c];
97 health[r][c] = if x <= 0 { 1 } else { x };
98 }
99 }
100
101 println!("-> {:?}", health);
102
103 health[0][0]
104 }
105}
106
107struct Sol312;
109
110impl Sol312 {
111 pub fn max_coins(nums: Vec<i32>) -> i32 {
112 let mut mem = vec![vec![0; nums.len()]; nums.len()];
113
114 fn search(mem: &mut Vec<Vec<i32>>, nums: &Vec<i32>, i: usize, j: usize) -> i32 {
115 if i > j {
116 return 0;
117 }
118
119 if i == j {
120 let mut coins = nums[i];
121 if i > 0 {
122 coins *= nums[i - 1];
123 }
124 if j < nums.len() - 1 {
125 coins *= nums[j + 1];
126 }
127 return coins;
128 }
129
130 if mem[i][j] > 0 {
131 return mem[i][j];
132 }
133
134 let mut xcoins = 0;
135 for k in i..=j {
136 let mut coins = nums[k];
137 if i > 0 {
138 coins *= nums[i - 1];
139 }
140 if j < nums.len() - 1 {
141 coins *= nums[j + 1];
142 }
143
144 if k > 0 {
145 coins += search(mem, nums, i, k - 1);
146 }
147 coins += search(mem, nums, k + 1, j);
148
149 xcoins = xcoins.max(coins);
150 }
151 mem[i][j] = xcoins;
152
153 xcoins
154 }
155
156 search(&mut mem, &nums, 0, nums.len() - 1)
157 }
158}
159
160struct Sol329 {}
162
163impl Sol329 {
164 pub fn longest_increasing_path(matrix: Vec<Vec<i32>>) -> i32 {
167 let mut dp = vec![vec![0; matrix[0].len()]; matrix.len()];
168
169 fn dfs((r, c): (usize, usize), matrix: &[Vec<i32>], dp: &mut [Vec<i32>]) {
170 println!("-> {:?}", (r, c));
171
172 if dp[r][c] != 0 {
173 return;
174 }
175
176 let v = matrix[r][c];
177
178 let mut steps = 1;
179 dp[r][c] = steps;
180
181 let dirs = [-1, 0, 1, 0, -1];
182 for d in 0..4 {
183 let (r, c) = (
184 r.wrapping_add_signed(dirs[d]),
185 c.wrapping_add_signed(dirs[d + 1]),
186 );
187
188 if r < matrix.len() && c < matrix[r].len() {
189 println!("-> . {:?}", (r, c));
190
191 if matrix[r][c] > v {
192 if dp[r][c] == 0 {
193 dfs((r, c), matrix, dp);
194 }
195
196 steps = steps.max(dp[r][c] + 1);
197 }
198 }
199 }
200
201 dp[r][c] = steps;
202 }
203
204 for (r, rows) in matrix.iter().enumerate() {
205 for c in 0..rows.len() {
206 if dp[r][c] == 0 {
207 dfs((r, c), &matrix, &mut dp);
208 }
209 }
210 }
211
212 println!("-> {dp:?}");
213
214 if let Some(&max) = dp.iter().flatten().max() {
215 return max;
216 }
217 1
218 }
219}
220
221struct Sol368;
223
224impl Sol368 {
225 pub fn largest_divisible_subset(nums: Vec<i32>) -> Vec<i32> {
226 let mut dp = vec![1; nums.len()];
227
228 let mut nums = nums;
229 nums.sort_unstable();
230
231 println!("-> {:?}", nums);
232
233 let mut longest = (1, 0);
234 for i in 0..nums.len() {
235 for j in 0..i {
236 if nums[i] % nums[j] == 0 {
237 dp[i] = dp[i].max(dp[j] + 1);
238
239 if dp[i] > longest.0 {
240 longest = (dp[i], i);
241 }
242 }
243 }
244 }
245
246 println!("-> {:?}", (longest, &dp));
247
248 let mut rst = vec![];
249
250 let mut n = nums[longest.1];
251 for i in (0..=longest.1).rev() {
252 if dp[i] == longest.0 && n % nums[i] == 0 {
253 rst.push(nums[i]);
254 n = nums[i];
255 longest.0 -= 1;
256 }
257 }
258 rst.reverse();
259
260 rst
261 }
262}
263
264struct Sol377;
266
267impl Sol377 {
268 pub fn combination_sum4(nums: Vec<i32>, target: i32) -> i32 {
269 let mut sums = vec![];
270 sums.push(1);
271
272 for t in 1..=target {
273 sums.push(
274 nums.iter()
275 .filter(|&n| t - n >= 0)
276 .map(|n| sums[(t - n) as usize])
277 .sum(),
278 );
279 }
280
281 println!("-> {:?}", sums);
282 sums[target as usize]
283 }
284}
285
286struct Sol516;
288
289impl Sol516 {
290 pub fn longest_palindrome_subseq(s: String) -> i32 {
291 let s = s.as_bytes();
292
293 let mut lps = vec![vec![0; s.len()]; s.len()];
294 for x in 0..s.len() {
295 lps[x][x] = 1;
296 for y in (0..x).rev() {
297 lps[x][y] = match s[x] == s[y] {
298 true => lps[x - 1][y + 1] + 2,
299 _ => lps[x - 1][y].max(lps[x][y + 1]),
300 };
301 }
302 }
303
304 println!("-> {:?}", lps);
305
306 let mut lcs = vec![vec![0; s.len() + 1]; s.len() + 1];
308 for x in 0..s.len() {
309 for y in 0..s.len() {
310 lcs[x + 1][y + 1] = match s[x] == s[s.len() - 1 - y] {
311 true => lcs[x][y] + 1,
312 _ => lcs[x][y + 1].max(lcs[x + 1][y]),
313 }
314 }
315 }
316 println!("-> {} {:?}", lcs[s.len()][s.len()], lcs);
317
318 lps[s.len() - 1][0]
319 }
320}
321
322struct Sol639 {}
324
325impl Sol639 {
326 pub fn num_decodings(s: String) -> i32 {
328 let s: Vec<_> = s.chars().collect();
329 const M: i64 = 1e9 as i64 + 7;
330
331 let mut dp = vec![0; s.len() + 1];
332 dp[0] = 1;
333 dp[1] = match s[0] {
334 '*' => 9,
335 '0' => 0,
336 _ => 1,
337 };
338
339 for (i, &chr) in s.iter().enumerate().skip(1) {
340 match chr {
341 '*' => {
342 dp[i + 1] = 9 * dp[i] % M;
343 dp[i + 1] += match s[i - 1] {
344 '1' => 9 * dp[i - 1] % M,
345 '2' => 6 * dp[i - 1] % M,
346 '*' => 15 * dp[i - 1] % M,
347 _ => 0,
348 };
349 }
350 _ => {
351 dp[i + 1] = if chr != '0' { dp[i] } else { 0 };
352 dp[i + 1] += match s[i - 1] {
353 '1' => dp[i - 1],
354 '2' => {
355 if s[i] <= '6' {
356 dp[i - 1]
357 } else {
358 0
359 }
360 }
361 '*' => (if s[i] <= '6' { 2 } else { 1 }) * dp[i - 1] % M,
362 _ => 0,
363 };
364 }
365 }
366 }
367
368 println!("-> {dp:?}");
369 (dp[s.len()] % M) as _
370 }
371}
372
373struct Sol730;
375
376impl Sol730 {
377 pub fn count_palindromic_subsequences(s: String) -> i32 {
380 use std::collections::HashMap;
381
382 let mut mem = HashMap::new();
383 let chrs: Vec<_> = s.chars().collect();
384
385 const M: i64 = 1e9 as i64 + 7;
386
387 fn search(
388 start: usize,
389 end: usize,
390 chrs: &[char],
391 mem: &mut HashMap<[usize; 2], i64>,
392 ) -> i64 {
393 if start >= end {
394 return 0;
395 }
396
397 if let Some(&count) = mem.get(&[start, end]) {
398 return count;
399 }
400
401 let mut count = 0;
402 for chr in 'a'..='d' {
403 match (
404 chrs[start..end].iter().position(|&v| v == chr),
405 chrs[start..end].iter().rev().position(|&v| v == chr),
406 ) {
407 (None, None) => continue,
408 (Some(l), Some(r)) => {
409 let r = end - start - r - 1;
410 println!("{start} {l} {chr} {r} {end}");
411 if l == r {
412 count += 1;
413 } else {
414 count += 2 + search(start + l + 1, start + r, chrs, mem);
415 }
416 }
417 (_, _) => {}
418 }
419 count %= M;
420 }
421
422 mem.insert([start, end], count);
423 println!("-> {mem:?}");
424
425 count
426 }
427
428 search(0, chrs.len(), &chrs, &mut mem) as _
429 }
430}
431
432struct Sol790;
434
435impl Sol790 {
436 pub fn num_tilings(n: i32) -> i32 {
438 fn two_states(n: i32) -> i32 {
439 if n == 1 || n == 2 {
440 return n;
441 }
442
443 let mut full = [0; 1000 + 1]; let mut lshape = [0; 1000 + 1]; (full[1], full[2], lshape[2]) = (1, 2, 1);
447
448 const M: i64 = 1e9 as i64 + 7;
449 for i in 3..=n as usize {
450 full[i] = (full[i - 1] + full[i - 2] + 2 * lshape[i - 1]) % M;
451 lshape[i] = (lshape[i - 1] + full[i - 2]) % M;
452 }
453
454 full[n as usize] as _
455 }
456 println!(":: {}", two_states(n));
457
458 if n == 1 || n == 2 {
459 return n;
460 }
461
462 const M: i64 = 1e9 as i64 + 7;
463 let mut dp = vec![0; n as usize + 1];
464
465 (dp[1], dp[2], dp[3]) = (1, 2, 5);
466 for i in 4..=n as usize {
467 dp[i] = (2 * dp[i - 1] + dp[i - 3]) % M;
468 }
469
470 println!("-> {:?}", dp);
471
472 dp[n as usize] as _
473 }
474}
475
476struct Sol808 {}
478
479impl Sol808 {
480 pub fn soup_servings(n: i32) -> f64 {
481 use std::collections::HashMap;
482
483 let n = (n + 24) / 25;
484 let mut memo = HashMap::new();
485
486 fn search(a: i32, b: i32, memo: &mut HashMap<(i32, i32), f64>) -> f64 {
487 if a <= 0 && b <= 0 {
488 return 0.5;
489 }
490 if a <= 0 {
491 return 1.0;
492 }
493 if b <= 0 {
494 return 0.0;
495 }
496
497 if let Some(&p) = memo.get(&(a, b)) {
498 return p;
499 }
500
501 let p = (search(a - 4, b, memo)
502 + search(a - 3, b - 1, memo)
503 + search(a - 2, b - 2, memo)
504 + search(a - 1, b - 3, memo))
505 / 4.0;
506 memo.insert((a, b), p);
507
508 p
509 }
510
511 for n in 1..=n {
512 if search(n, n, &mut memo) > 1.0 - 0.00001 {
513 return 1.0;
514 }
515 }
516
517 search(n, n, &mut memo)
518 }
519}
520
521struct Sol873;
523
524impl Sol873 {
525 pub fn len_longest_fib_subseq(arr: Vec<i32>) -> i32 {
526 use std::collections::HashSet;
527
528 let mut hset = HashSet::new();
529 for n in &arr {
530 hset.insert(n);
531 }
532
533 println!("-> {:?}", hset);
534
535 let mut xlen = 0;
536 for l in 0..arr.len() {
537 for r in l + 1..arr.len() {
538 let mut prv = arr[r];
539 let mut cur = arr[l] + arr[r];
540
541 let mut clen = 2;
542 while hset.contains(&cur) {
543 (prv, cur) = (cur, prv + cur);
544
545 clen += 1;
546 xlen = xlen.max(clen);
547 }
548 }
549 }
550
551 xlen
552 }
553}
554
555struct Sol1039 {}
557
558impl Sol1039 {
559 pub fn min_score_triangulation(values: Vec<i32>) -> i32 {
560 use std::collections::HashMap;
561
562 let mut cache = HashMap::new();
563 fn search(
564 cache: &mut HashMap<(usize, usize), i32>,
565 i: usize,
566 j: usize,
567 values: &[i32],
568 ) -> i32 {
569 if i + 2 > j {
570 return 0;
571 }
572 if i + 2 == j {
573 return values[i] * values[(i + 1) & (j - 1)] * values[j];
574 }
575
576 if let Some(&score) = cache.get(&(i, j)) {
577 score
578 } else {
579 let score = (i + 1..j)
580 .map(|k| {
581 search(cache, i, k, values)
582 + values[i] * values[k] * values[j]
583 + search(cache, k, j, values)
584 })
585 .min()
586 .unwrap();
587 cache.insert((i, j), score);
588 score
589 }
590 }
591
592 let score = search(&mut cache, 0, values.len() - 1, &values);
593 println!("-> {cache:?}");
594
595 score
596 }
597}
598
599struct Sol1092;
601
602impl Sol1092 {
603 pub fn shortest_common_supersequence(str1: String, str2: String) -> String {
605 let (str1, str2) = (str1.as_bytes(), str2.as_bytes());
606
607 let mut dp = vec![vec![0; str2.len() + 1]; str1.len() + 1];
609 for (x, chr1) in str1.iter().enumerate() {
610 for (y, chr2) in str2.iter().enumerate() {
611 dp[x + 1][y + 1] = match chr1 == chr2 {
612 true => dp[x][y] + 1,
613 false => dp[x][y + 1].max(dp[x + 1][y]),
614 };
615 }
616 }
617
618 println!("-> LCS :: {:?}", dp);
619
620 let mut rst = vec![];
621 let (mut x, mut y) = (str1.len(), str2.len());
622 while x > 0 || y > 0 {
623 if x > 0 && y > 0 && str1[x - 1] == str2[y - 1] {
624 rst.push(str1[x - 1]);
625 x -= 1;
626 y -= 1;
627 } else if x > 0 && (y == 0 || dp[x - 1][y] >= dp[x][y - 1]) {
628 rst.push(str1[x - 1]);
629 x -= 1;
630 } else if y > 0 {
631 rst.push(str2[y - 1]);
632 y -= 1;
633 }
634 }
635 rst.reverse();
636
637 String::from_utf8(rst).expect("")
638 }
639
640 pub fn scs_recursive(str1: String, str2: String) -> String {
642 use std::collections::HashMap;
643
644 let mut mem = HashMap::new();
645 fn search<'l>(
646 str1: &'l str,
647 str2: &'l str,
648 mem: &mut HashMap<(&'l str, &'l str), String>,
649 ) -> String {
650 match (str1.len(), str2.len()) {
651 (0, 0) => "".to_string(),
652 (0, _) => str2.to_string(),
653 (_, 0) => str1.to_string(),
654 _ => {
655 println!("-> {:?}", (&str1, &str2));
656
657 if let Some(rst) = mem.get(&(str1, str2)) {
658 return rst.to_string();
659 }
660
661 match str1[0..1].cmp(&str2[0..1]) {
662 std::cmp::Ordering::Equal => {
663 let scs = search(&str1[1..], &str2[1..], mem);
664 mem.insert((str1, str2), str1[0..1].to_string() + &*scs);
665 }
666 _ => {
667 let scs1 = search(&str1[1..], str2, mem);
668 let scs2 = search(str1, &str2[1..], mem);
669
670 if scs1.len() <= scs2.len() {
671 mem.insert((str1, str2), str1[0..1].to_string() + &*scs1);
672 } else {
673 mem.insert((str1, str2), str2[0..1].to_string() + &*scs2);
674 }
675 }
676 }
677
678 mem[&(str1, str2)].to_string()
679 }
680 }
681 }
682
683 let rst = search(&str1, &str2, &mut mem);
684 println!("-> {:?}", mem);
685
686 rst
687 }
688}
689
690struct Sol1277 {}
692
693impl Sol1277 {
694 pub fn count_squares(matrix: Vec<Vec<i32>>) -> i32 {
695 use std::cmp::min;
696
697 let (cols, rows) = (matrix[0].len(), matrix.len());
698
699 let mut counts = vec![vec![0; cols + 1]; rows + 1];
700 let mut count = 0;
701
702 for r in 0..rows {
703 for c in 0..cols {
704 if matrix[r][c] == 1 {
705 counts[r + 1][c + 1] =
706 1 + min(counts[r][c], min(counts[r + 1][c], counts[r][c + 1]));
707 count += counts[r + 1][c + 1];
708 }
709 }
710 }
711
712 count
713 }
714}
715
716struct Sol1504 {}
718
719impl Sol1504 {
720 pub fn num_submat(mat: Vec<Vec<i32>>) -> i32 {
721 let cols = mat[0].len();
722
723 let mut count = 0;
724 let mut counts = vec![0; cols * cols];
725
726 for row in mat.iter() {
727 for c in 0..cols {
728 let mut flag = true;
729 for k in 0..=c {
730 if flag && row[c - k] == 0 {
731 flag = false;
732 }
733
734 if flag {
735 counts[c * cols + k] += 1;
736 count += counts[c * cols + k];
737 } else {
738 counts[c * cols + k] = 0;
739 }
740 }
741 }
742 }
743
744 count
745 }
746}
747
748struct Sol1524;
750
751impl Sol1524 {
752 pub fn num_of_subarrays(arr: Vec<i32>) -> i32 {
754 const M: u32 = 1e9 as u32 + 7;
755
756 let mut edp = vec![0; arr.len()]; let mut odp = vec![0; arr.len()]; match arr[arr.len() - 1] & 1 {
760 1 => odp[arr.len() - 1] = 1,
761 _ => edp[arr.len() - 1] = 1,
762 }
763
764 for i in (0..arr.len() - 1).rev() {
765 match arr[i] & 1 {
766 1 => {
767 odp[i] = (1 + edp[i + 1]) % M;
768 edp[i] = odp[i + 1];
769 }
770 _ => {
771 edp[i] = (1 + edp[i + 1]) % M;
772 odp[i] = odp[i + 1];
773 }
774 }
775 }
776
777 println!("-> {:?}", odp);
778
779 (odp.into_iter().sum::<u32>() % M) as i32
780 }
781
782 fn num_of_subarrays_psum(arr: Vec<i32>) -> i32 {
783 const M: i32 = 1e9 as i32 + 7;
784
785 let mut count = 0;
786 let (mut evens, mut odds) = (1, 0);
787
788 let mut psum = 0;
789 for n in arr {
790 psum += n;
791
792 count += match psum & 1 {
793 1 => {
794 odds += 1;
795 evens
796 }
797 _ => {
798 evens += 1;
799 odds
800 }
801 } % M;
802 }
803
804 count % M
805 }
806}
807
808struct Sol1749;
810
811impl Sol1749 {
812 pub fn max_absolute_sum(nums: Vec<i32>) -> i32 {
813 let mut rst = 0;
814 let (mut xsum, mut nsum) = (i32::MIN, i32::MAX);
815
816 let mut pfx = 0;
817 for n in nums {
818 pfx += n;
819
820 xsum = xsum.max(pfx);
821 nsum = nsum.min(pfx);
822
823 use std::cmp::Ordering::*;
824 match pfx.cmp(&0) {
825 Greater => rst = rst.max(pfx.max(pfx - nsum)),
826 Less => rst = rst.max((-pfx).max(xsum - pfx)),
827 _ => (),
828 }
829 }
830
831 rst
832 }
833}
834
835struct Sol1751 {}
837
838impl Sol1751 {
839 pub fn max_values(mut events: Vec<Vec<i32>>, k: i32) -> i32 {
840 events.sort_by_key(|v| v[0]);
841 println!("-> {events:?}");
842
843 let rsearch = |target| {
844 let (mut l, mut r) = (0, events.len());
845 while l < r {
846 let m = l + ((r - l) >> 1);
847 if events[m][0] <= target {
848 l = m + 1;
849 } else {
850 r = m;
851 }
852 }
853
854 l
855 };
856
857 let mut dp = vec![vec![0; events.len() + 1]; 1 + k as usize];
858 for start in (0..events.len()).rev() {
859 let x = rsearch(events[start][1]);
860 for k in 1..=k as usize {
861 dp[k][start] = (dp[k][start + 1]).max(dp[k - 1][x] + events[start][2]);
862 }
863 }
864
865 dp[k as usize][0]
866 }
867}
868
869struct Sol1857 {}
871
872impl Sol1857 {
873 pub fn largest_path_value(colors: String, edges: Vec<Vec<i32>>) -> i32 {
876 use std::collections::{HashMap, HashSet};
877
878 let mut gadj: HashMap<usize, HashSet<usize>> = HashMap::new();
879 for edge in edges.iter() {
880 gadj.entry(edge[0] as usize)
881 .or_default()
882 .insert(edge[1] as usize);
883 }
884 println!("-> {gadj:?}");
885
886 let colors = colors.as_bytes();
887 let mut dp = vec![[0; 26]; colors.len()];
888
889 #[derive(Clone, PartialEq, Debug)]
890 enum OpColor {
891 NotVisited, Visiting, Visited, }
895
896 fn search(
897 v: usize,
898 dp: &mut [[usize; 26]],
899 colors: &[u8],
900 gadj: &HashMap<usize, HashSet<usize>>,
901 coloring: &mut [OpColor],
902 ) -> bool {
903 if coloring[v] != OpColor::NotVisited {
904 return true;
905 }
906
907 coloring[v] = OpColor::Visiting;
908
909 if let Some(uset) = gadj.get(&v) {
910 for &u in uset.iter() {
911 match coloring[u] {
912 OpColor::Visited => {}
913 OpColor::Visiting => return true,
914 OpColor::NotVisited => {
915 if search(u, dp, colors, gadj, coloring) {
916 return true;
917 }
918 }
919 }
920
921 for color in 0..26 {
922 dp[v][color] = dp[v][color].max(dp[u][color]);
923 }
924 }
925 }
926
927 dp[v][(colors[v] - b'a') as usize] += 1;
928
929 coloring[v] = OpColor::Visited;
930 false
931 }
932
933 let mut coloring = vec![OpColor::NotVisited; colors.len()];
934 for src in 0..colors.len() {
935 if coloring[src] == OpColor::NotVisited
936 && search(src, &mut dp, colors, &gadj, &mut coloring)
937 {
938 return -1;
939 }
940 }
941
942 println!("-> {dp:?}");
943
944 match dp
945 .iter()
946 .map(|row| match row.iter().max() {
947 Some(&xrow) => xrow,
948 _ => 0,
949 })
950 .max()
951 {
952 Some(xgraph) => xgraph as i32,
953 _ => 0,
954 }
955 }
956}
957
958struct Sol1931;
960
961impl Sol1931 {
962 pub fn color_the_grid(m: i32, n: i32) -> i32 {
964 use std::collections::HashMap;
965
966 let mut masks = HashMap::new();
967 (0..3i32.pow(m as u32)).for_each(|mask| {
968 let mut colors = vec![];
969
970 let mut v = mask;
971 for _ in 0..m {
972 colors.push(v % 3);
973 v /= 3;
974 }
975
976 if !colors.windows(2).any(|w| w[0] == w[1]) {
977 masks.insert(mask, colors);
978 }
979 });
980
981 println!("-> Color Masks: {masks:?}");
982
983 let mut adjacents = HashMap::new();
984 for (&mask1, color1) in &masks {
985 for (&mask2, color2) in &masks {
986 if !color1
987 .iter()
988 .zip(color2.iter())
989 .any(|(color1, color2)| color1 == color2)
990 {
991 adjacents.entry(mask1).or_insert(vec![]).push(mask2);
992 }
993 }
994 }
995
996 println!("-> Rows Adjacent: {adjacents:?}");
997
998 const M: i32 = 1_000_000_007;
999
1000 {
1001 let mut dp_cur = vec![0; [1, 3, 9, 27, 81, 243][m as usize]];
1002 for &mask in masks.keys() {
1003 dp_cur[mask as usize] = 1;
1004 }
1005 for _ in 1..n {
1006 let mut dp_next = vec![0; dp_cur.len()];
1007 for mask in 0..[1, 3, 9, 27, 81, 243][m as usize] {
1008 if dp_cur[mask as usize] > 0
1009 && let Some(adjacent) = adjacents.get(&mask)
1010 {
1011 dp_next[mask as usize] = adjacent
1012 .iter()
1013 .fold(0, |count, &mask| (count + dp_cur[mask as usize]) % M);
1014 }
1015 }
1016 dp_cur = dp_next;
1017 }
1018 println!(":: {}", dp_cur.iter().fold(0, |count, &n| (count + n) % M));
1019 }
1020
1021 let mut dp_cur = HashMap::new();
1022 for &mask in masks.keys() {
1023 dp_cur.insert(mask, 1);
1024 }
1025 for _ in 1..n {
1026 let mut dp_next = HashMap::new();
1027 for &mask in dp_cur.keys() {
1028 if let Some(adjacent) = adjacents.get(&mask) {
1029 dp_next.insert(
1030 mask,
1031 adjacent.iter().fold(0, |count, &mask| {
1032 (count + dp_cur.get(&mask).unwrap_or(&0)) % M
1033 }),
1034 );
1035 }
1036 }
1037 dp_cur = dp_next;
1038 }
1039
1040 dp_cur.values().fold(0, |count, &n| (count + n) % M)
1041 }
1042}
1043
1044struct Sol2140;
1046
1047impl Sol2140 {
1048 pub fn most_points(questions: Vec<Vec<i32>>) -> i64 {
1049 use std::cmp::Ordering::*;
1050
1051 let mut dp = vec![[0i64; 2]; questions.len() + 1];
1052
1053 for (i, q) in questions.iter().enumerate().rev() {
1054 println!("-> {:?}", (i, &q));
1055
1056 dp[i][0] = dp[i + 1][0].max(dp[i + 1][1]);
1057
1058 let [pts, skip] = q[..2] else { unreachable!() };
1059 let next = i + 1 + skip as usize;
1060
1061 dp[i][1] = pts as i64
1062 + match next.cmp(&questions.len()) {
1063 Less => dp[next][0].max(dp[next][1]),
1064 _ => 0,
1065 };
1066
1067 println!("-> {:?}", dp);
1068 }
1069
1070 println!(":: {:?}", dp[0]);
1071
1072 dp[0][0].max(dp[0][1])
1073 }
1074
1075 fn recursive(questions: Vec<Vec<i32>>) -> i64 {
1077 let mut mem = vec![0; questions.len()];
1078
1079 fn search(i: usize, questions: &[Vec<i32>], mem: &mut [i64]) -> i64 {
1080 if i >= questions.len() {
1081 return 0;
1082 }
1083
1084 if mem[i] > 0 {
1085 return mem[i];
1086 }
1087
1088 let [pts, skip] = questions[i][..] else {
1089 unreachable!()
1090 };
1091 mem[i] = search(i + 1, questions, mem)
1092 .max(pts as i64 + search(i + 1 + skip as usize, questions, mem));
1093
1094 mem[i]
1095 }
1096
1097 let pts = search(0, &questions, &mut mem);
1098 println!("-> Mem: {:?}", mem);
1099
1100 pts
1101 }
1102}
1103
1104struct Sol2163 {}
1106
1107impl Sol2163 {
1108 pub fn minimum_difference(nums: Vec<i32>) -> i64 {
1109 use std::cmp::Reverse;
1110 use std::collections::BinaryHeap;
1111
1112 let n = nums.len() / 3;
1113 let mut part1 = vec![0i64; n + 1];
1114 let mut sum = 0i64;
1115
1116 let mut ql = BinaryHeap::new();
1117 for &v in nums.iter().take(n) {
1118 sum += v as i64;
1119 ql.push(v);
1120 }
1121
1122 part1[0] = sum;
1123 for i in n..2 * n {
1124 sum += nums[i] as i64;
1125 ql.push(nums[i]);
1126 sum -= ql.pop().unwrap() as i64;
1127 part1[i - (n - 1)] = sum;
1128 }
1129
1130 let mut part2 = 0i64;
1131
1132 let mut qr = BinaryHeap::new();
1133 for i in (2 * n..3 * n).rev() {
1134 part2 += nums[i] as i64;
1135 qr.push(Reverse(nums[i]));
1136 }
1137
1138 let mut m_diff = part1[n] - part2;
1139 for i in (n..2 * n).rev() {
1140 part2 += nums[i] as i64;
1141 qr.push(Reverse(nums[i]));
1142 if let Some(Reverse(val)) = qr.pop() {
1143 part2 -= val as i64;
1144 }
1145 m_diff = m_diff.min(part1[i - n] - part2);
1146 }
1147
1148 m_diff
1149 }
1150}
1151
1152struct Sol2787 {}
1154
1155impl Sol2787 {
1156 pub fn number_of_ways(n: i32, x: i32) -> i32 {
1157 const M: i64 = 1e9 as i64 + 7;
1158
1159 let n = n as usize;
1160 let mut ks = vec![vec![0; n + 1]; n + 1]; let items: Vec<_> = (0..=n).map(|p| (p as i64).pow(x as u32)).collect();
1163 println!("-> {items:?}");
1164
1165 ks[0][0] = 1;
1166 for item in 1..=n {
1167 let power = items[item] as usize;
1168 for capacity in 0..=n {
1169 ks[item][capacity] = ks[item - 1][capacity];
1170 if power <= capacity {
1171 ks[item][capacity] = (ks[item][capacity] + ks[item - 1][capacity - power]) % M
1172 }
1173 }
1174 }
1175
1176 println!("-> {ks:?}");
1177
1178 ks[n][n] as _
1179 }
1180}
1181
1182struct Sol2836;
1184
1185impl Sol2836 {
1186 pub fn get_max_function_value(receiver: Vec<i32>, k: i64) -> i64 {
1187 println!(" || {:?}", receiver);
1192
1193 let (bits, nodes) = (k.ilog2() as usize + 1, receiver.len());
1194
1195 let mut far = vec![vec![0; bits]; nodes];
1196 (0..bits).for_each(|p| {
1197 (0..nodes).for_each(|i| match p {
1198 0 => far[i][0] = receiver[i] as usize,
1199 _ => far[i][p] = far[far[i][p - 1]][p - 1],
1200 })
1201 });
1202
1203 println!(" -> {:?}", far);
1204
1205 let mut score = vec![vec![0i64; bits]; nodes];
1206 (0..bits).for_each(|p| {
1207 (0..nodes).for_each(|i| match p {
1208 0 => score[i][0] = receiver[i] as i64,
1209 _ => score[i][p] = score[i][p - 1] + score[far[i][p - 1]][p - 1],
1210 })
1211 });
1212
1213 println!(" -> {:?}", score);
1214
1215 (0..nodes).fold(0, |xscore, istart| {
1216 xscore.max({
1217 let (mut iscore, mut i) = (0, istart);
1218 (0..bits).rev().for_each(|p| {
1219 if (1 << p) & k != 0 {
1220 iscore += score[i][p];
1221 i = far[i][p];
1222 }
1223 });
1224 iscore + istart as i64
1225 })
1226 })
1227 }
1228}
1229
1230struct Sol2901;
1232
1233impl Sol2901 {
1234 pub fn get_words_in_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
1235 let mut dists = vec![vec![]; groups.len()];
1236 for (i, x) in words.iter().enumerate() {
1237 for y in words.iter().take(i) {
1238 dists[i].push(if x.len() != y.len() {
1239 0
1240 } else {
1241 x.chars()
1242 .zip(y.chars())
1243 .fold(0, |d, (x, y)| if x == y { d } else { d + 1 })
1244 });
1245 }
1246 dists[i].push(0);
1247 }
1248
1249 println!("-> {dists:?}");
1250
1251 fn valid_distance(x: &str, y: &str) -> bool {
1252 use std::cmp::Ordering::Equal;
1253 match x.len().cmp(&y.len()) {
1254 Equal => {
1255 x.chars()
1256 .zip(y.chars())
1257 .filter(|(x, y)| x != y)
1258 .collect::<Vec<_>>()
1259 .len()
1260 == 1
1261 }
1262 _ => false,
1263 }
1264 }
1265
1266 let mut picks = vec![usize::MAX; groups.len()];
1267 let mut longest = vec![1; groups.len()];
1268
1269 let (mut lmax, mut ilast) = (1, 0);
1270
1271 for i in 1..groups.len() {
1272 for j in 0..i {
1273 if groups[j] != groups[i]
1274 && (dists[i][j] == 1 && valid_distance(&words[i], &words[j]))
1275 && longest[i] < longest[j] + 1
1276 {
1277 longest[i] = longest[j] + 1;
1278 picks[i] = j;
1279 }
1280 }
1281
1282 if longest[i] > lmax {
1283 (lmax, ilast) = (longest[i], i);
1284 }
1285 }
1286
1287 println!("-> {lmax} | {longest:?}");
1288 println!("-> {ilast} | {picks:?}");
1289
1290 let mut lss = vec![];
1291 while ilast != usize::MAX {
1292 lss.push(words[ilast].to_owned());
1293 ilast = picks[ilast];
1294 }
1295 lss.reverse();
1296
1297 lss
1298 }
1299}
1300
1301struct Sol2999;
1303
1304impl Sol2999 {
1305 pub fn number_of_powerful_int(start: i64, finish: i64, limit: i32, s: String) -> i64 {
1306 let finish = finish.to_string();
1307 let start = format!("{:0>width$}", start.to_string(), width = finish.len());
1308
1309 println!("-> {:?}", (&start, &finish, limit, &s));
1310
1311 let mut mem = vec![-1; finish.len()];
1312
1313 fn search(
1314 i: usize,
1315 slimit: bool,
1316 start: &[u8],
1317 flimit: bool,
1318 finish: &[u8],
1319 limit: u8,
1320 s: &[u8],
1321 mem: &mut [i64],
1322 ) -> i64 {
1323 println!("-> {:?}", (i, slimit, flimit));
1324
1325 if i == (start.len() & finish.len()) {
1326 return 1;
1327 }
1328 if !slimit && !flimit && mem[i] != -1 {
1329 return mem[i];
1330 }
1331
1332 let mut count = 0;
1333 let sdigit = if slimit { start[i] } else { b'0' };
1334 let fdigit = if flimit { finish[i] } else { b'9' };
1335
1336 if i < finish.len() - s.len() {
1337 for digit in sdigit..=fdigit.min(limit) {
1338 count += search(
1339 i + 1,
1340 slimit && digit == start[i],
1341 start,
1342 flimit && digit == finish[i],
1343 finish,
1344 limit,
1345 s,
1346 mem,
1347 );
1348 }
1349 } else {
1350 let digit = s[i - (finish.len() - s.len())];
1351 if sdigit <= digit && digit <= fdigit.min(limit) {
1352 count += search(
1353 i + 1,
1354 slimit && digit == start[i],
1355 start,
1356 flimit && digit == finish[i],
1357 finish,
1358 limit,
1359 s,
1360 mem,
1361 );
1362 }
1363 }
1364
1365 if !slimit && !flimit {
1366 mem[i] = count;
1367 }
1368 count
1369 }
1370
1371 search(
1372 0,
1373 true,
1374 start.as_bytes(),
1375 true,
1376 finish.as_bytes(),
1377 b'0' + limit as u8,
1378 s.as_bytes(),
1379 &mut mem,
1380 )
1381 }
1382}
1383
1384struct Sol3068 {}
1386
1387impl Sol3068 {
1388 pub fn maximum_value_sum(nums: Vec<i32>, k: i32, edges: Vec<Vec<i32>>) -> i64 {
1389 println!("-> {edges:?}");
1390
1391 fn recursive(
1392 start: usize,
1393 xors: usize,
1394 nums: &[i32],
1395 k: i32,
1396 memo: &mut [[i64; 2]],
1397 ) -> i64 {
1398 if start == nums.len() {
1399 return match xors & 1 {
1400 0 => 0,
1401 _ => i64::MIN,
1402 };
1403 }
1404
1405 if memo[start][xors] != -1 {
1406 return memo[start][xors];
1407 }
1408
1409 let xsum = (nums[start] as i64 + recursive(start + 1, xors, nums, k, memo))
1410 .max((nums[start] ^ k) as i64 + recursive(start + 1, xors ^ 1, nums, k, memo));
1411 memo[start][xors] = xsum;
1412 xsum
1413 }
1414
1415 let mut memo = vec![[-1, -1]; nums.len()];
1416 println!(":: {}", recursive(0, 0, &nums, k, &mut memo));
1417
1418 let tabulation = || {
1419 let mut dp = vec![[-1, -1]; nums.len() + 1];
1420 (dp[nums.len()][0], dp[nums.len()][1]) = (0, i64::MIN);
1421
1422 for i in (0..nums.len()).rev() {
1423 for xor in [0, 1] {
1424 dp[i][xor] = (dp[i + 1][xor] + nums[i] as i64)
1425 .max(dp[i + 1][xor ^ 1] + (nums[i] ^ k) as i64);
1426 }
1427 }
1428
1429 dp[0][0]
1430 };
1431 println!(":: {}", tabulation());
1432
1433 let mut changes: Vec<_> = nums.iter().map(|&n| (n ^ k) - n).collect();
1434 changes.sort_unstable_by_key(|&n| std::cmp::Reverse(n));
1435
1436 changes
1437 .chunks(2)
1438 .take_while(|chunk| chunk.len() == 2)
1439 .inspect(|chunk| println!("-> {chunk:?}"))
1440 .map(|v| (v[0] + v[1]) as i64)
1441 .take_while(|&diff| diff > 0)
1442 .sum::<i64>()
1443 + nums.iter().map(|&n| n as i64).sum::<i64>()
1444 }
1445}
1446
1447struct Sol3333 {}
1449
1450impl Sol3333 {
1451 pub fn possible_string_count(word: String, k: i32) -> i32 {
1454 let mut f = 1;
1455 let mut freqs = word
1456 .chars()
1457 .collect::<Vec<_>>()
1458 .windows(2)
1459 .fold(vec![], |mut freqs, w| {
1460 if w[0] == w[1] {
1461 f += 1;
1462 } else {
1463 freqs.push(f);
1464 f = 1;
1465 }
1466 freqs
1467 });
1468 freqs.push(f);
1469 println!("-> {freqs:?}");
1470
1471 const M: i64 = 1e9 as i64 + 7;
1472
1473 let k = k as usize;
1474 let total = freqs.iter().fold(1, |total, &f| f * total % M);
1475 if freqs.len() >= k {
1476 return total as _;
1477 }
1478
1479 let mut counts = vec![vec![0; k]; freqs.len() + 1];
1480 counts[0][0] = 1;
1481
1482 for g in 0..freqs.len() {
1483 for l in 1..k {
1484 for x in 1..=freqs[g] as usize {
1485 if l >= x {
1486 counts[g + 1][l] = (counts[g + 1][l] + counts[g][l - x]) % M;
1487 }
1488 }
1489 }
1490 }
1491
1492 counts
1493 .last()
1494 .unwrap()
1495 .iter()
1496 .fold(total, |total, &count| (total - count + M) % M) as _
1497 }
1498}
1499
1500struct Sol3335;
1502
1503impl Sol3335 {
1504 pub fn length_after_transformations(s: String, t: i32) -> i32 {
1506 const M: i32 = 1e9 as i32 + 7;
1507
1508 let mut freqs = vec![vec![0; 26]; t as usize + 1];
1509 for chr in s.as_bytes() {
1510 freqs[0][(chr - b'a') as usize] += 1;
1511 }
1512
1513 for i in 1..=t as usize {
1514 freqs[i][0] = freqs[i - 1][25];
1515 freqs[i][1] = (freqs[i - 1][0] + freqs[i - 1][25]) % M;
1516 for chr in 2..26 {
1517 freqs[i][chr] = freqs[i - 1][chr - 1]
1518 }
1519 }
1520
1521 println!("-> {freqs:?}");
1522
1523 freqs[t as usize].iter().fold(0, |t, &l| (t + l) % M)
1524 }
1525}
1526
1527struct Sol3337;
1529
1530impl Sol3337 {
1531 pub fn length_after_transformations(s: String, t: i32, nums: Vec<i32>) -> i32 {
1533 type M = [[i64; 26]; 26];
1542
1543 let mut m: M = [[0; 26]; 26];
1544 for chr in 0..26 {
1545 for t in 1..=nums[chr] as usize {
1546 m[chr][(chr + t) % 26] = 1;
1547 }
1548 }
1549
1550 let mut freq = [0; 26];
1551 for chr in s.as_bytes() {
1552 freq[(chr - b'a') as usize] += 1;
1553 }
1554
1555 const MOD: i64 = 1e9 as i64 + 7;
1556
1557 fn mcopy(t: &mut M, f: &M) {
1558 for i in 0..26 {
1559 for j in 0..26 {
1560 t[i][j] = f[i][j];
1561 }
1562 }
1563 }
1564
1565 fn mzero(m: &mut M) {
1566 for row in m.iter_mut() {
1567 for v in row.iter_mut() {
1568 *v = 0;
1569 }
1570 }
1571 }
1572
1573 fn matrix_multiply(m: &mut M, a: &M, b: &M) {
1574 mzero(m);
1575
1576 for i in 0..26 {
1577 for (k, b_k) in b.iter().enumerate() {
1578 let a_ik = a[i][k];
1579 if a_ik != 0 {
1580 for (j, b_k_j) in b_k.iter().enumerate() {
1581 m[i][j] = (m[i][j] + a_ik * b_k_j) % MOD;
1582 }
1583 }
1584 }
1585 }
1586 }
1587
1588 fn square_exponentiation(b: &M, mut e: i32) -> M {
1590 let mut power: M = [[0; 26]; 26];
1591 for (d, row) in power.iter_mut().enumerate() {
1592 row[d] = 1;
1593 }
1594
1595 let mut base: M = [[0; 26]; 26];
1596 mcopy(&mut base, b);
1597
1598 let mut t: M = [[0; 26]; 26];
1599 while e > 0 {
1600 if e & 1 == 1 {
1601 matrix_multiply(&mut t, &power, &base);
1602 mcopy(&mut power, &t);
1603 }
1604
1605 matrix_multiply(&mut t, &base, &base);
1606 mcopy(&mut base, &t);
1607
1608 e >>= 1;
1609 }
1610
1611 power
1612 }
1613
1614 let power: M = square_exponentiation(&m, t);
1615
1616 println!("-> M^t {power:?}");
1617
1618 let mut tfreq = [0; 26];
1619 for i in 0..26 {
1620 for j in 0..26 {
1621 tfreq[i] = (tfreq[i] + freq[i] * power[i][j]) % MOD;
1622 }
1623 }
1624
1625 println!("-> {tfreq:?}");
1626
1627 tfreq.iter().fold(0, |l, &n| (l + n) % MOD) as _
1628 }
1629}
1630
1631struct Sol3363 {}
1633
1634impl Sol3363 {
1635 pub fn max_collected_fruits(mut fruits: Vec<Vec<i32>>) -> i32 {
1636 fn walk(fruits: &[Vec<i32>]) -> i32 {
1637 let n = fruits.len();
1638 let mut prv = vec![i32::MIN; n];
1639 prv[n - 1] = fruits[0][n - 1];
1640
1641 let mut cur = vec![i32::MIN; n];
1642 for (r, fruits) in fruits.iter().enumerate().skip(1).take(fruits.len() - 2) {
1643 for c in (n - 1 - r).max(r + 1)..n {
1644 let mut best = prv[c];
1645 if c > 0 {
1646 best = best.max(prv[c - 1]);
1647 }
1648 if c < n - 1 {
1649 best = best.max(prv[c + 1]);
1650 }
1651 cur[c] = best + fruits[c];
1652 }
1653 (0..n).for_each(|i| prv[i] = cur[i]);
1654 }
1655
1656 prv[n - 1]
1657 }
1658
1659 let mut xcolls = (0..fruits.len()).map(|d| fruits[d][d]).sum();
1660 xcolls += walk(&fruits);
1661 for r in 0..fruits.len() {
1662 for c in 0..r {
1663 (fruits[r][c], fruits[c][r]) = (fruits[c][r], fruits[r][c]);
1664 }
1665 }
1666 xcolls += walk(&fruits);
1667
1668 xcolls
1669 }
1670}
1671
1672struct Sol3459 {}
1674
1675impl Sol3459 {
1676 pub fn len_of_v_diagonal(grid: Vec<Vec<i32>>) -> i32 {
1677 use std::collections::HashMap;
1678
1679 const DIRS: [(isize, isize); 4] = [(1, 1), (1, -1), (-1, -1), (-1, 1)];
1680 let mut cache: HashMap<(usize, usize, usize, bool), i32> = HashMap::new();
1681
1682 fn search(
1683 grid: &[Vec<i32>],
1684 y: usize,
1685 x: usize,
1686 dir: usize,
1687 turned: bool,
1688 target: i32,
1689 cache: &mut HashMap<(usize, usize, usize, bool), i32>,
1690 ) -> i32 {
1691 let (r, c) = (
1692 y.wrapping_add_signed(DIRS[dir].0),
1693 x.wrapping_add_signed(DIRS[dir].1),
1694 );
1695
1696 if r >= grid.len() || c >= grid[0].len() || grid[r][c] != target {
1697 return 0;
1698 }
1699
1700 if let Some(&steps) = cache.get(&(r, c, dir, turned)) {
1701 return steps;
1702 }
1703
1704 let mut steps = search(grid, r, c, dir, turned, 2 - grid[r][c], cache);
1705 if !turned {
1706 steps = search(grid, r, c, (dir + 1) % 4, true, 2 - grid[r][c], cache).max(steps);
1707 }
1708 cache.insert((r, c, dir, turned), steps + 1);
1709
1710 println!("-> {cache:?}");
1711
1712 steps + 1
1713 }
1714
1715 grid.iter().enumerate().fold(0, |x_steps, (r, row)| {
1716 x_steps.max(
1717 row.iter()
1718 .enumerate()
1719 .filter_map(|(c, &g)| if g == 1 { Some(c) } else { None })
1720 .map(|c| {
1721 (0..4)
1722 .map(|dir| search(&grid, r, c, dir, false, 2, &mut cache) + 1)
1723 .max()
1724 .unwrap_or(0)
1725 })
1726 .max()
1727 .unwrap_or(0),
1728 )
1729 })
1730 }
1731}
1732
1733#[cfg(test)]
1734mod tests;