• 天黑了,来个算法题为你助眠


    给出一些不同颜色的盒子 boxes ,盒子的颜色由不同的正数表示。

    你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k * k 个积分。

    返回 你能获得的最大积分和 。

    示例 1:

    输入:boxes = [1,3,2,2,2,3,4,3,1]
    输出:23
    解释:
    [1, 3, 2, 2, 2, 3, 4, 3, 1] 
    ----> [1, 3, 3, 4, 3, 1] (3*3=9 分) 
    ----> [1, 3, 3, 3, 1] (1*1=1 分) 
    ----> [1, 1] (3*3=9 分) 
    ----> [] (2*2=4 分)

    示例2:

    输入:boxes = [1,1,1]

    输出:9

    示例3: 

     输入:boxes = [1]

    输出:1

    提示:

    • 1 <= boxes.length <= 100
    • 1 <= boxes[i] <= 100
    1. // 无缓存数组版本
    2. public int removeBoxes(int[] boxes) {
    3. if (boxes == null || boxes.length < 1) return 0;
    4. if (boxes.length == 1) return 1;
    5. return process(boxes, 0, boxes.length - 1, 0);
    6. }
    7. // 在前面有 k 个数与 arr[L] 相同的情况下
    8. // 移除 L ~ R 的盒子,得到的最大得分
    9. public int process(int[] arr, int L, int R, int k) {
    10. if (L > R) return 0;
    11. // 如果arr[L]的数与前面的一起消掉
    12. int ans = process(arr, L + 1, R, 0) + (k + 1) * (k + 1);
    13. // arr[L] 和前面的 k 个数一起作为下一个等于arr[L] 没有消掉的数
    14. for (int i = L + 1; i <= R; i++) {
    15. if (arr[i] == arr[L]) {
    16. ans = Math.max(ans, process(arr, L + 1, i - 1, 0) + process(arr,i, R, k + 1));
    17. }
    18. }
    19. return ans;
    20. }
    21. // 通过缓存数组大幅提升速度
    22. // 与前面的方法是一样的道理,只不过用了一个数组存了算过的东西避免递归时反复计算浪费时间
    23. public static int removeBoxes(int[] boxes) {
    24. int N = boxes.length;
    25. int[][][] dp = new int[N][N][N];
    26. return process(boxes, 0, boxes.length - 1, 0, dp);
    27. }
    28. public static int process(int[] arr, int L, int R, int K, int[][][] dp) {
    29. if (L > R) return 0;
    30. if (dp[L][R][K] != 0) return dp[L][R][K];
    31. int max = process(arr, L + 1, R, 0, dp) + (K + 1) * (K + 1);
    32. for (int i = L + 1; i <= R; i++) {
    33. if (arr[i] == arr[L]) {
    34. max = Math.max(max,
    35. process(arr, L + 1, i - 1, 0, dp) + process(arr, i, R, K + 1, dp));
    36. }
    37. }
    38. dp[L][R][K] = max;
    39. return max;
    40. }
    41. // 进一步优化常数项时间
    42. public static int removeBoxes(int[] boxes) {
    43. int N = boxes.length;
    44. int[][][] dp = new int[N][N][N];
    45. return process(boxes, 0, boxes.length - 1, 0, dp);
    46. }
    47. // 如果arr[L]后面有和它相等的一串数,假设到 last 都是和 arr[L] 相等的,
    48. // 那么直接把 原来前面K个和 L ~ last - 1 位置的数当成last位置前面与其相等的部分
    49. public static int process(int[] arr, int L, int R, int K, int[][][] dp) {
    50. if (L > R) return 0;
    51. if (dp[L][R][K] != 0) return dp[L][R][K];
    52. int last = L;
    53. while (last + 1 <= R && arr[last + 1] == arr[L]) {
    54. last++;
    55. }
    56. int pre = last - L + K;
    57. int max = process(arr, last + 1, R, 0, dp) + (pre + 1) * (pre + 1);
    58. for (int i = last + 2; i <= R; i++) {
    59. if (arr[i] == arr[L] && arr[i - 1] != arr[L]) {
    60. max = Math.max(max,
    61. process(arr, last + 1, i - 1, 0, dp) + process(arr, i, R, pre + 1, dp));
    62. }
    63. }
    64. dp[L][R][K] = max;
    65. return max;
    66. }

    题目来源:546. 移除盒子

    打败 100% 。虽然看了大佬题解,但看懂后写出来也很高兴

     

     

  • 相关阅读:
    [AI OpenAI] 保护前沿AI研究基础设施的安全
    PHP 数据类型
    腾讯公布机器人最新进展:“轮滑小子”Ollie拥有触觉,人机交互更友好
    C# 拨号面板 高亮显示
    面试突击:说一下 Spring 事务传播机制?
    win7的虚拟机版优化
    Java基础面试-重载和重写的区别
    LuatOS-SOC接口文档(air780E)-- i2s - 数字音频
    Web前端 Promise 入门 【尚硅谷】
    Day3 最短路 最小生成树 拓扑排序
  • 原文地址:https://blog.csdn.net/qq_61557294/article/details/126952367