石子合并(区间dp)-java

石子合并问题是经典的区间dp问题,我们需要枚举中间端点k的情况从而来推出dp数组的值。

文章目录

前言

一、石子合并问题

二、算法思路

1.问题思路

2.状态递推公式

二、代码如下

代码如下(示例):

2.读入数据

3.代码运行结果如下:

总结


前言

石子合并问题是经典的区间dp问题,我们需要枚举中间端点k的情况从而来推出dp数组的值。


提示:以下是本篇文章正文内容,下面案例可供参考

一、石子合并问题

设有 N 堆石子排成一排,其编号为 1,2,3,…,N。

每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N堆石子合并成为一堆。

每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。

例如有 4 堆石子分别为 1 3 5 2, 我们可以先合并 1、2 堆,代价为 4,得到 4 5 2, 又合并 1、2 堆,代价为 9,得到 9 2,再合并得到 11,总代价为 4+9+11=24;

如果第二步是先合并 2、3堆,则代价为 7,得到 4 7,最后一次合并代价为 11,总代价为 4+7+11=22。

问题是:找出一种合理的方法,使总的代价最小,输出最小代价。

二、算法思路

1.问题思路

我们引入二维数组dp,dp[i][j]表示的含义是从第i堆,合并到第j堆所需要的最小代价数。

 图1.1思路模拟

 我们可以通过枚举区间长度len,从1枚举n,当然区间长度为1的时候,说明只有一堆石子,就不要合并,代价为0。

然后我们在从1开始枚举左区间的起始端点i,i的值从1枚举到n。我们知道区间长度len,知道左端点i,那么我们就可以得到区间的右端点j=i+len-1。

此时我们再枚举中间端点k,k的值的话从i枚举到j-1,因为我们最后用k将区间分成两堆,分别是i到k堆和k+1到j堆,那么我们k的取值就是从i到j-1。

那么dp[i][j]的值就是从第i堆到第k堆的最小代价数加上第k+1堆到第j堆的最小代价数再加上最后两堆的代价数,我们通过观察可以发现最后两堆的合并一定是第i堆到k堆的连续合并和后面从第k+1堆到第j堆的连续合并之和,那么最后一次就相当于求区间和,我们可以通过前缀和数组的方法来进行处理。

2.状态递推公式

当i=j时,即就一堆:

dp[i][j] = 0

当 枚举中间端点k时:

dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1])

j-1\geqslant k\geqslant i 

注:其中一维数组s表示石子质量的前缀和数组,故求第i堆到第j堆石子重量的和为

       s[j]-s[i-1] 

dp数组构建代码如下:

        //区间长度
        for(int len = 2; len <= n;len++){
            //枚举左端端点
            for(int i = 1; i + len - 1 <= n;i++){
                //最右端端点
                int j = i + len -1;
                //初始化
                dp[i][j] = Integer.MAX_VALUE;mei
                //左右端点相等,那么就一堆,不需要进行操作
                if(i == j){
                    dp[i][j] = 0;
                }
                //枚举中间端点
                for(int k = i; k <= j-1;k++){
                    dp[i][j] = Math.min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1]);
                }
            }
        }

二、代码如下

代码如下(示例):

import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;

public class 石子合并 {
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    public static void main(String[] args) {
        Scanner  sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int n = sc.nextInt();
        int[] s = new int[310];
        int[][] dp = new int[310][310];
        for(int i = 1; i <= n;i++){
            s[i] = sc.nextInt();
        }
        for(int i = 1;i <= n;i++){
            s[i] = s[i]+s[i-1];
        }
        //区间长度
        for(int len = 2; len <= n;len++){
            //枚举左端端点
            for(int i = 1; i + len - 1 <= n;i++){
                //最右端端点
                int j = i + len -1;
                //初始化
                dp[i][j] = Integer.MAX_VALUE;
                //左右端点相等,那么就一堆,不需要进行操作
                if(i == j){
                    dp[i][j] = 0;
                }
                //枚举中间端点
                for(int k = i; k <= j-1;k++){
                    dp[i][j] = Math.min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1]);
                }
             }
        }
        pw.println(dp[1][n]);
        pw.flush();
    }
}

2.读入数据

代码如下(示例):

4
1 3 5 2

3.代码运行结果如下:

22

总结

石子合并问题是经典的区间dp问题,我们需要枚举中间端点k的情况从而来推出dp数组的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/537308.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java开发面试题分享

目录 1、简述MyISAM和InnoDB的区别 2、简述Hash和B树索引的区别 3、简述MyBatis的实现逻辑 4、#{}和${}的区别 5、简述Mybatis的优缺点 6、当实体类中的属性名和表中的字段名不一样时怎么办&#xff1f; 7、resultType与resultMap的区别 8、如何执行批量插入 9、Mybat…

蓝桥杯-数组切分

问题描述 已知一个长度为 N 的数组: A1,A2,A3,...AN 恰好是1~ N的一个排列。现 在要求你将 4 数组切分成若干个 (最少一个,最多 N 个)连续的子数组,并且 每个子数组中包含的整数恰好可以组成一段连续的自然数。 例如对于 4 1,3,2,4,一共有 5 种切分方法: 1324:每个单独的数显然…

(五)PostgreSQL的管理工具pgAdmin

PostgreSQL的管理工具pgAdmin pgAdmin 是一款流行的开源图形界面管理工具&#xff0c;用于 PostgreSQL 数据库的管理和开发。它提供了一个易于使用的界面&#xff0c;允许用户执行各种数据库任务&#xff0c;如创建和修改数据库对象&#xff08;表、视图、索引等&#xff09;、…

Springboot实现链路追踪功能

前言 在日常开发中&#xff0c;一个业务的实现往往会调用很多个方法&#xff0c;当我们去看日志的时候&#xff0c;各种接口的日志打印出来&#xff0c;看着就头疼&#xff0c;压根没办法去定位&#xff0c;而链路追踪就能很好的帮助我们去查看接口从头至尾依次调用了哪些方法…

UE5 在骨骼动画模型上绘制贴图

参考&#xff1a;Unreal 5.1 - How to paint damage textures and other effects on skeletal meshes 针对模型&#xff0c;在运行状态下通过射线指定一定范围&#xff0c;添加材质效果。 核心思路 通过射线获取命中点&#xff0c;作为材质参数材质中&#xff0c;命中的世界…

护眼台灯品牌哪个好?2024五大护眼台灯排行榜分享

​护眼台灯作为家庭中常见的照明工具&#xff0c;其存在几乎成为了现代生活的标配。家长们往往会为孩子购置一台&#xff0c;供学习和阅读使用&#xff1b;同时&#xff0c;它也是学生和办公人员在夜晚工作学习的必备之物。然而&#xff0c;市面上的一些普通台灯可能存在着种种…

【XR806开发板试用】使用硬件SPI驱动TFT液晶屏显示图片

【开发背景】 在完成开发板呼吸灯效果后&#xff08;【XR806开发板试用】使用PWM模块模拟手机呼吸灯提示功能&#xff09;&#xff0c;考虑到显示界面过于单一&#xff0c;如果想要呈现更多的信息就很困难了&#xff0c;刚好之前买过一个TFT液晶屏&#xff0c;正在某个角落吃灰…

OV证书——提升企业在线身份信誉

简介 在当今的数字化时代&#xff0c;网络安全与用户信任成为企业线上运营的基石&#xff0c;而SSL/TLS证书则是确保网站数据传输安全、提升网站信誉度的关键工具之一。其中&#xff0c;组织验证&#xff08;OV&#xff09;证书作为一种特殊类型的SSL证书&#xff0c;通过深入…

Vivado抓信号——提高效率的工具化生成XDC(Python脚本)

操作目录 一、要抓取信号的txt列表二、操作流程 通常情况下&#xff0c;Vivado上板抓取信号的方法主要有两类&#xff1a; &#xff08;1&#xff09;通过在信号前添加(mark_debug“true”)&#xff0c;综合完之后点击Set Up Debug&#xff0c;将需要抓取的信号添加进去&#x…

linux学习:文件类型、文件操作、系统IO、内存映射

目录 文件类别 文件操作 系统 IO 头文件 打开文件 关闭文件 文件描述符 读写 例子 拷贝文件 偏移量 其他接口 mmap()映射 文件类别 普通文件&#xff08;regular&#xff09;&#xff1a;存在于外部存储器中&#xff0c;用于存储普通数据。目录文件&#xff08;d…

蓝桥杯,,,,,,

辗转相除求最大公约数 #include<iostream> using namespace std;int gcd(int a, int b)//求最大公约数&#xff0c;如果返回值为1&#xff0c;最大公约数只有1&#xff0c;为所求 {return b ? gcd(b, a % b) : a; } int main() {int count 0;for(int i1;i<2020;i)f…

进口PFA容量瓶高纯透明聚四氟乙烯材质耐强酸碱PFA定容瓶

PFA容量瓶&#xff0c;也叫特氟龙容量瓶&#xff0c;是用于配制标准浓度溶液的实验室器皿&#xff0c;是有着细长颈、梨形肚的耐强腐蚀平底塑料瓶&#xff0c;颈上有标线&#xff0c;可直接配置标准溶液和准确稀释溶液以及制备样品溶液。 因其有着不易碎、材质纯净、化学稳定性…

Unity Android后处理AO报错

整体流程&#xff1a; 1.添加AO效果 2.Mode 选择 Multi-scale Volumetric Occlusion 3.保证Project Settings - Player - Other Settings - Rendering - Graphic API 内包含 Vulkan 原因&#xff1a; 1.Post Processing文档&#xff1a;https://docs.unity3d.com/Packages/…

探索点云与KD-Tree配对的方法

比较点云是处理和分析点云数据的关键步骤。然而,由于各个扫描之间固有的差异,无法进行逐点比较。因此,点云分析的第一步也是主要步骤是将点配对以进行有意义的比较。 配对点是区分表面变形和运动分析的关键任务。这个过程不仅为变形分析提供了见解,还使我们能够通过比较不…

如何用 Readwise Reader 定制提示词 AI 自动辅助处理信息?

抵御「信息过载」&#xff0c;你需要这样的利器。 痛点 知识工作者的痛点是非常明显的——如果你是一名老师、学生&#xff0c;或是平时需要跟许多资料打交道的人&#xff0c;想必你会经历过信息过载。 信息过载有时候不仅是数量问题&#xff0c;还是一个类型问题。很多不同的信…

【话题】AI技术创业有那些机会,简单探讨下

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 背景机会一、引言二、AI技术的创业机遇1.智能服务行业的兴起2.数据驱动的业务模式创新3.AI与产业融合的创新发展 三、AI技术创业的挑战1.技术门槛高2.法规政策的不确定性…

奎芯科技:智能时代的芯片上游企业如何突破?

半导体IP&#xff08;Intellectual Property&#xff0c;知识产权&#xff09;&#xff0c;通常也称作IP核&#xff08;IP core&#xff09;&#xff0c;指芯片设计中预先设计、验证好的功能模块&#xff0c;主要服务于芯片设计&#xff0c;因部分通用功能模块在芯片中被反复使…

03-JAVA设计模式-享元模式

享元模式 什么是享元模式 享元模式&#xff08;Flyweight Pattern&#xff09;是一种对象结构型设计模式&#xff0c;用于减少创建对象的数量&#xff0c;以减少内存占用和提高系统性能。它通过共享已经存在的对象来避免创建大量相似的对象&#xff0c;从而降低内存消耗。 在…

SAP 计划策略82简介

前面的文章中我们已经测试了很多才策略,10、11、40、50、70、60、63 80策略。 本文将重点说明ATO模式下82策略的使用场景,计划策略82是SAP提供的另一种基于按单生产思想的计划策略,由客户的需求来直接驱动直接生产,是一个按单生产的场景。 1、首先我们先看下系统后台82策略…