【每日一题Day167】LC1000合并石头的最低成本 | 区间dp

简介: 【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
合并石头的最低成本【LC1000】

N 堆石头排成一排,第 i 堆中有 stones[i] 块石头。

每次*移动(move)*需要将连续的K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的总数。

找出把所有石头合并成一堆的最低成本。如果不可能,返回 -1

等校车的时候用手机看了一眼,感觉是区间dp,但这几天都在练习区间dp,心里想不会那么巧吧


然后坐下来就没往区间dp想,首先先确定石头堆数和K的关系,然后想到贪心,先合并的K堆石, 在之后还会与其他石头进行合并,因此优先合并连续k堆石头最小的k堆,然后删除合并的石头,加入新合并后的,然后再进行删除,直到石头的堆数为k。然后遇到了错误的案例,上面的贪心不是最优的,然后想着那就每次枚举所有的k kk堆石头吧,然后超时了。最后放弃,看题解,emm,真的是区间dp…

递归+记忆化
  • 思路

image.png



image.png

ab2b46ceba15558ecaa66f5d90333cb0.png

实现

class Solution {
    int[][][] dp;
    int[] sum;
    int k;
    public int mergeStones(int[] stones, int k) {
        int n = stones.length;
        if ((n - 1) % (k - 1) != 0) return -1;
        dp = new int[n + 1][n + 1][k + 1];
        sum = new int[n + 1];
        this.k = k;
        for (int i = 0; i <= n; i++){
            for (int j = 0; j <= n; j++){
                Arrays.fill(dp[i][j], -1);
            }
        }
        for (int i = 0; i < n; i++){
            sum[i + 1] = sum[i] + stones[i];
        }
        return dfs(0, n - 1 , 1);
    }
    public int dfs(int i, int j, int p){
        if (dp[i][j][p] != -1) return dp[i][j][p];
        if (p == 1){
            return i == j ? 0 : dfs(i, j, k) + sum[j + 1] - sum[i];
        }
        int res = Integer.MAX_VALUE;
        for (int m = i; m < j; m += k - 1){
            res = Math.min(res, dfs(i, m, 1) + dfs(m + 1, j, p - 1));
        }
        dp[i][j][p] = res;
        return res;
    }
}

image.png

class Solution {
    private int[][] memo;
    private int[] s;
    private int k;
    public int mergeStones(int[] stones, int k) {
        int n = stones.length;
        if ((n - 1) % (k - 1) > 0) // 无法合并成一堆
            return -1;
        s = new int[n + 1];
        for (int i = 0; i < n; i++)
            s[i + 1] = s[i] + stones[i]; // 前缀和
        this.k = k;
        memo = new int[n][n];
        for (int i = 0; i < n; ++i)
            Arrays.fill(memo[i], -1); // -1 表示还没有计算过
        return dfs(0, n - 1);
    }
    private int dfs(int i, int j) {
        if (i == j) return 0; // 只有一堆石头,无需合并
        if (memo[i][j] != -1) return memo[i][j];
        int res = Integer.MAX_VALUE;
        for (int m = i; m < j; m += k - 1)
            res = Math.min(res, dfs(i, m) + dfs(m + 1, j));
        if ((j - i) % (k - 1) == 0) // 可以合并成一堆
            res += s[j + 1] - s[i];
        return memo[i][j] = res;
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-cost-to-merge-stones/solutions/2207235/tu-jie-qu-jian-dpzhuang-tai-she-ji-yu-yo-ppv0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

image.png

动态规划

class Solution {
    public int mergeStones(int[] stones, int k) {
        int n = stones.length;
        if ((n - 1) % (k - 1) > 0) // 无法合并成一堆
            return -1;
        var s = new int[n + 1];
        for (int i = 0; i < n; i++)
            s[i + 1] = s[i] + stones[i]; // 前缀和
        var f = new int[n][n];
        for (int i = n - 1; i >= 0; --i)
            for (int j = i + 1; j < n; ++j) {
                f[i][j] = Integer.MAX_VALUE;
                for (int m = i; m < j; m += k - 1)
                    f[i][j] = Math.min(f[i][j], f[i][m] + f[m + 1][j]);
                if ((j - i) % (k - 1) == 0) // 可以合并成一堆
                    f[i][j] += s[j + 1] - s[i];
            }
        return f[0][n - 1];
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-cost-to-merge-stones/solutions/2207235/tu-jie-qu-jian-dpzhuang-tai-she-ji-yu-yo-ppv0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

image.png


目录
相关文章
|
SQL 大数据 开发工具
大数据Hive窗口函数应用实例 2
大数据Hive窗口函数应用实例
306 0
|
XML Java Maven
【Maven技术专题】「实战开发系列」盘点Maven项目中打包需要注意到的那点事儿
【Maven技术专题】「实战开发系列」盘点Maven项目中打包需要注意到的那点事儿
288 1
|
安全 Java 调度
多线程【进阶版】(下)
多线程【进阶版】
174 0
|
10月前
|
SQL 监控 安全
浅析Waf优缺点:硬件Waf、软件Waf、云Waf之总结
Web应用防火墙(WAF)是一种专门针对Web应用攻击的防护产品,主要分为硬件WAF、软件WAF和云WAF三种形态。硬件WAF部署简便、防护范围广,但价格昂贵且存在误杀风险;软件WAF开箱即用、功能丰富,但可能占用较多内存,适合中小型网站;云WAF部署简单、维护成本低,但存在被绕过和数据泄露的风险。RASP(运行时应用自保护)是一种新兴的安全技术,通过将保护程序注入应用程序,实现实时检测和阻断攻击,具有低误报率、维护成本低等优势,但也面临部署困难和可能影响性能的问题。未来,WAF防护技术将朝着机器学习、词法分析、行为识别和大数据关联分析等方向发展。
1108 6
|
11月前
|
机器学习/深度学习 人工智能 5G
5G天线设计的关键要点解析
5G天线设计的关键要点解析
460 64
|
jenkins 持续交付 开发工具
【gitlab】旧的gitlab项目迁移新的gitlab
【gitlab】旧的gitlab项目迁移新的gitlab
2019 0
|
消息中间件 存储 关系型数据库
实时计算 Flink版产品使用问题之同步时,上游批量删除大量数据(如20万条),如何提高删除效率
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
JSON 前端开发 Java
"《图书管理系统》利用SpringMvc$Spring$MyBatis (实操九)(一) "
"《图书管理系统》利用SpringMvc$Spring$MyBatis (实操九)(一) "
264 0
|
机器学习/深度学习 运维 自然语言处理
探索机器学习在金融欺诈检测中的应用
【5月更文挑战第3天】 随着金融科技的迅猛发展,机器学习作为其核心推动力之一,正逐渐改变着我们对金融服务安全与效率的理解。本文将深入探讨机器学习技术在金融欺诈检测领域内的应用现状与前景。通过分析多种算法和实际案例,我们揭示了如何利用机器学习提高识别欺诈行为的准确率,降低金融机构的风险损失。同时,文章还将讨论在此过程中遇到的挑战及未来的发展趋势,为读者提供一个全面而深入的视角。
|
Linux API 开发者
元象大模型开源30款量化版本 加速低成本部署丨附教程
元象大模型一次性发布30款量化版本,全开源,无条件免费商用。

热门文章

最新文章