首页 > 试题广场 >

小明打砖块

[编程题]小明打砖块
  • 热度指数:590 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小明在玩一个消除游戏。这个消除游戏有点特别。游戏中,你会得到 n 个一维排列的有各自颜色的砖块。
消除的时候,你有三种消除方案。你可以单消一个砖块,这样你可以得到 a 的得分;如果两个颜色一样的砖块在一起,你可以将这两个砖块一起消除获得 b 的得分;如果三个颜色一样的砖块在一期,你可以将这三个砖块一起消除获得 c 的得分。
消除后,被消除的砖块自动消失,被消除砖块的左右两端的砖块将在消除之后挨在一起。
小明想知道在最优策略下他能得到多少得分。

输入描述:
第一行4个整数n,a,b,c,表示砖块数量,和一消/二消/三消的得分。
接下来一行n个整数,第i 个整数 s_i 表示第 i 个砖块的颜色。

1 \leq s_i \leq n \leq 300, 0 \leq a,b,c \leq 10000


输出描述:
输出最高得分
示例1

输入

8 1 3 7
3 1 3 1 3 2 2 3

输出

14
import java.util.Scanner;

// DP[i][j]:单消、双消、三消
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int a = in.nextInt(), b = in.nextInt(), c = in.nextInt();
        int[] s = new int[n];
        for (int i = 0; i < n; i++) {
            s[i] = in.nextInt();
        }

        int[][] dp = new int[n][n];
        for (int len = 1; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1, res = 0;

                // 单消:枚举s[k]  
                for (int k = i; k <= j; k++) {
                    int l = (i <= k - 1) ? dp[i][k - 1] : 0; // s[i]还在
                    int r = (k + 1 <= j) ? dp[k + 1][j] : 0;
                    res = Math.max(res, a + l + r);
                }

                // 双消:枚举s[k]和s[i]匹配
                for (int k = i + 1; k <= j; k++) {
                    if (s[k] != s[i]) continue;
                    int l = (i + 1 <= k - 1) ? dp[i + 1][k - 1] : 0; // s[i]没了
                    int r = (k + 1 <= j)     ? dp[k + 1][j]     : 0;
                    res = Math.max(res, b + l + r);
                }

                // 三消:枚举s[k]、s[t]和s[i]匹配
                for (int k = i + 1; k < j; k++) {
                    if (s[k] != s[i]) continue;
                    for (int t = k + 1; t <= j; t++) {
                        if (s[t] != s[i]) continue;
                        int l = (i + 1 <= k - 1) ? dp[i + 1][k - 1] : 0;
                        int m = (k + 1 <= t - 1) ? dp[k + 1][t - 1] : 0;
                        int r = (t + 1 <= j)     ? dp[t + 1][j]     : 0;
                        res = Math.max(res, c + l + m + r);
                    }
                }
                dp[i][j] = res;
            }
        }
        System.out.println(dp[0][n - 1]);
    }
}

发表于 2025-10-27 22:37:39 回复(0)