棒的切割

  1. //! Solves the rod-cutting problem
  2. use std::cmp::max;
  3. /// `rod_cut(p)` returns the maximum possible profit if a rod of length `n` = `p.len()`
  4. /// is cut into up to `n` pieces, where the profit gained from each piece of length
  5. /// `l` is determined by `p[l - 1]` and the total profit is the sum of the profit
  6. /// gained from each piece.
  7. ///
  8. /// # Arguments
  9. /// - `p` - profit for rods of length 1 to n inclusive
  10. ///
  11. /// # Complexity
  12. /// - time complexity: O(n^2),
  13. /// - space complexity: O(n^2),
  14. ///
  15. /// where n is the length of `p`.
  16. pub fn rod_cut(p: &[usize]) -> usize {
  17. let n = p.len();
  18. // f is the dynamic programming table
  19. let mut f = vec![0; n];
  20. for i in 0..n {
  21. let mut max_price = p[i];
  22. for j in 1..=i {
  23. max_price = max(max_price, p[j - 1] + f[i - j]);
  24. }
  25. f[i] = max_price;
  26. }
  27. // accomodate for input with length zero
  28. if n != 0 {
  29. f[n - 1]
  30. } else {
  31. 0
  32. }
  33. }
  34. #[cfg(test)]
  35. mod tests {
  36. use super::rod_cut;
  37. #[test]
  38. fn test_rod_cut() {
  39. assert_eq!(0, rod_cut(&[]));
  40. assert_eq!(15, rod_cut(&[5, 8, 2]));
  41. assert_eq!(10, rod_cut(&[1, 5, 8, 9]));
  42. assert_eq!(25, rod_cut(&[5, 8, 2, 1, 7]));
  43. assert_eq!(87, rod_cut(&[0, 0, 0, 0, 0, 87]));
  44. assert_eq!(49, rod_cut(&[7, 6, 5, 4, 3, 2, 1]));
  45. assert_eq!(22, rod_cut(&[1, 5, 8, 9, 10, 17, 17, 20]));
  46. assert_eq!(60, rod_cut(&[6, 4, 8, 2, 5, 8, 2, 3, 7, 11]));
  47. assert_eq!(30, rod_cut(&[1, 5, 8, 9, 10, 17, 17, 20, 24, 30]));
  48. assert_eq!(12, rod_cut(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]));
  49. }
  50. }