当前位置: 首页 > news >正文

P1775 石子合并(弱化版)

P1775 石子合并(弱化版)

题目描述

设有 N ( N ≤ 300 ) N(N \le 300) N(N300) 堆石子排成一排,其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi (mi1000)。现在要将这 N N N 堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻。合并时由于选择的顺序不同,合并的总代价也不相同。试找出一种合理的方法,使总的代价最小,并输出最小代价。

输入格式

第一行,一个整数 N N N

第二行, N N N 个整数 m i m_i mi

输出格式

输出文件仅一个整数,也就是最小代价。

样例 #1

样例输入 #1

4
2 5 3 1

样例输出 #1

22

题解分析

这道题目可以通过区间动态规划来解决。我们的目标是将多个石子堆合并成一堆,而每次合并相邻的两堆所需要的代价是这两堆石子质量之和。因为每次合并顺序不同,总的合并代价也会不同,所以我们要找到一种顺序,使得总的合并代价最小。

动态规划状态定义

我们设 dp[i][j] 表示将第 i 堆到第 j 堆的石子合并成一堆的最小代价。这个问题的关键是,如何从已经合并好的子区间合并出更大的区间。

状态转移

  1. 初始状态

    • 对于任何单独的一堆石子,即 dp[i][i],合并代价为 0,因为它已经是一个单独的堆,不需要合并。
  2. 状态转移方程
    对于区间 [i, j],我们可以选择一个中间点 k 来分割区间 [i, j],使得左半部分是 [i, k],右半部分是 [k+1, j],然后将这两个子区间的结果合并。合并这两个子区间的代价为这两个子区间的质量和。

    因此,dp[i][j] 可以通过以下方式计算:
    d p [ i ] [ j ] = min ⁡ ( d p [ i ] [ k ] + d p [ k + 1 ] [ j ] + sum [ i , j ] ) 其中 k ∈ [ i , j − 1 ] dp[i][j] = \min(dp[i][k] + dp[k+1][j] + \text{sum}[i, j]) \quad \text{其中} \quad k \in [i, j-1] dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[i,j])其中k[i,j1]
    其中,sum[i, j] 表示从 ij 的石子质量之和。

  3. 如何计算区间的质量和?
    使用前缀和来快速计算任意区间 [i, j] 的石子质量和。前缀和数组 sum[i] 记录了从第 1 堆到第 i 堆的质量之和。通过前缀和,我们可以在常数时间内得到任意区间 [i, j] 的和:
    sum [ i , j ] = sum [ j ] − sum [ i − 1 ] \text{sum}[i, j] = \text{sum}[j] - \text{sum}[i-1] sum[i,j]=sum[j]sum[i1]

算法复杂度

  • 时间复杂度
    • 我们需要填充一个 dp 数组,其中有 O(N^2) 个状态。
    • 对于每一个 dp[i][j],我们需要枚举中间点 k,这使得每个状态的转移需要 O(N) 的时间。
    • 因此,总的时间复杂度是 O(N^3),其中 N 最大为 300,这使得该算法在给定输入限制下是可行的。

代码实现

#include <iostream>
#include <vector>
#include <algorithm>#define int long long
using namespace std;const int N = 300 + 10;
const int INF = 1e18;int dp[N][N];    // dp[i][j] 存储合并区间 [i, j] 的最小代价
int sum[N];      // sum[i] 存储从 1 到 i 的前缀和void solve() {int n;cin >> n;vector<int> v(n + 1);// 输入石子的质量for (int i = 1; i <= n; ++i) {cin >> v[i];}// 计算前缀和sum[0] = 0;for (int i = 1; i <= n; ++i) {sum[i] = sum[i - 1] + v[i];}// 初始化 dp 数组for (int i = 1; i <= n; ++i) {dp[i][i] = 0;  // 单个堆合并代价为0}// 动态规划计算for (int len = 2; len <= n; ++len) {  // len 表示区间长度for (int l = 1; l <= n - len + 1; ++l) {  // l 表示区间左端点int r = l + len - 1;  // r 表示区间右端点dp[l][r] = INF;  // 初始化为无穷大for (int k = l; k < r; ++k) {  // k 为中间点,分割区间dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r] + sum[r] - sum[l - 1]);}}}// 输出最小代价cout << dp[1][n] << endl;
}signed main() {solve();return 0;
}

代码分析

  1. 输入和前缀和的计算

    • 我们先读取石子的质量,并计算出前缀和数组 sum[],这样可以快速计算任何区间 [i, j] 的石子质量和。
  2. 初始化动态规划数组

    • 对于每个区间 [i, i],即单独一堆石子,合并代价为 0,因此 dp[i][i] = 0
  3. 动态规划过程

    • 我们使用三重循环来计算所有区间的最小代价:
      • 外层循环遍历区间的长度 len
      • 中层循环遍历区间的左端点 l
      • 内层循环遍历中间点 k,将区间 [l, r] 分为 [l, k][k+1, r] 两个子区间,计算合并代价。
  4. 最小代价输出

    • 最终,dp[1][n] 即为将所有石子堆合并成一堆的最小代价。

复杂度分析

  • 时间复杂度:

    • O(N^3),其中 N 是石子的堆数。由于我们有三重循环,时间复杂度为 O(N^3),每次计算都需要 O(1) 的时间。
  • 空间复杂度:

    • O(N^2),因为 dp 数组的大小为 N x N,用于存储每个区间的最小合并代价。

总结

这道题目通过动态规划和前缀和技巧,能够有效地计算出合并所有石子堆的最小代价。虽然时间复杂度是 O(N^3),但由于 N 的最大值为 300,算法在时间限制内是可以接受的。

相关文章:

P1775 石子合并(弱化版)

P1775 石子合并&#xff08;弱化版&#xff09; 题目描述 设有 N ( N ≤ 300 ) N(N \le 300) N(N≤300) 堆石子排成一排&#xff0c;其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,⋯,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi​ (mi​≤…...

一文回顾讲解Java中的集合框架

这篇文章以提问的方式总结回顾下Java中常见的集合框架 Java中的集合框架可以分为两条大的支线&#xff1a;Collection和Map Collection,主要由List、Set、Queue组成&#xff1b; List是有序&#xff0c;可重复的集合&#xff0c;典型代表有封装了动态数组的ArrayList和封装了链…...

多模态论文笔记——NaViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文NaViT&#xff08;Native Resolution ViT&#xff09;&#xff0c;将来自不同图像的多个patches打包成一个单一序列——称为Patch n’ Pack—…...

智能小区物业管理系统推动数字化转型与提升用户居住体验

内容概要 在当今快速发展的社会中&#xff0c;智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具&#xff0c;更是一种推动数字化转型的重要力量。它通过高效的技术手段&#xff0c;将物业管理与用户居住体验紧密结合&#xff0c;无疑为社区带…...

I2C基础知识

引言 这里祝大家新年快乐&#xff01;前面我们介绍了串口通讯协议&#xff0c;现在我们继续来介绍另一种常见的简单的串行通讯方式——I2C通讯协议。 一、什么是I2C I2C 通讯协议&#xff08;Inter-Integrated Circuit&#xff09;是由Phiilps公司在上个世纪80年代开发的&#…...

护眼好帮手:Windows显示器调节工具

在长时间使用电脑的过程中&#xff0c;显示器的亮度和色温对眼睛的舒适度有着重要影响。传统的显示器调节方式不仅操作繁琐&#xff0c;而且在低亮度下容易导致色彩失真。因此&#xff0c;今天我想为大家介绍一款适用于Windows系统的护眼工具&#xff0c;它可以帮助你轻松调节显…...

MongoDb user自定义 role 添加 action(collStats, EstimateDocumentCount)

使用 mongosh cd mongsh_bin_path mongosh “mongodb://user:passip:port/db”这样就直接进入了对应的db 直接输入&#xff1a; 这样 role “read_only_role" 就获得了3个 action&#xff0c; 分别是 查询&#xff0c;列举集合&#xff0c;集合元数据查询 P.S: 如果没有 …...

mysql学习笔记-数据库其他调优策略

1、如何定位调优问题 用户的反馈&#xff08;主要&#xff09; 日志分析&#xff08;主要&#xff09; 服务器资源使用监控 数据库内部状况监控 2、调优的维度和步骤 第1步&#xff1a;选择适合的 DBMS 第2步&#xff1a;优化表设计 第3步&#xff1a;优化逻辑查询 第4步&am…...

Office / WPS 公式、Mathtype 公式输入花体字、空心字

注&#xff1a;引文主要看注意事项。 1、Office / WPS 公式中字体转换 花体字 字体选择 “Eulid Math One” 空心字 字体选择 “Eulid Math Two” 使用空心字时&#xff0c;一般不用斜体&#xff0c;取消勾选 “斜体”。 2、Mathtype 公式输入花体字、空心字 2.1 直接输…...

(done) MIT6.S081 2023 学习笔记 (Day6: LAB5 COW Fork)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/cow.html 任务1&#xff1a;Implement copy-on-write fork(hard) (完成) 现实中的问题如下&#xff1a; xv6中的fork()系统调用会将父进程的用户空间内存全部复制到子进程中。如果父进程很大&#xff0c;复制过程…...

SYN Flooding的攻击原理

SYN Flooding是一种常见的网络攻击方式&#xff0c;属于拒绝服务攻击&#xff08;DoS&#xff09;的一种&#xff0c;其攻击原理主要是利用了TCP协议的三次握手过程&#xff0c;以下是具体介绍&#xff1a; TCP三次握手正常流程 第一次握手&#xff1a;客户端向服务器发送一个…...

MYSQL--一条SQL执行的流程,分析MYSQL的架构

文章目录 第一步建立连接第二部解析 SQL第三步执行 sql预处理优化阶段执行阶段索引下推 执行一条select 语句中间会发生什么&#xff1f; 这个是对 mysql 架构的深入理解。 select * from product where id 1;对于mysql的架构分层: mysql 架构分成了 Server 层和存储引擎层&a…...

cmd命令行无法进入D:盘怎么办

我找到了一个方法就是 增加一个/d cd /d d: 如下图,我不仅可以进入d盘符下&#xff0c;还可以访问盘符下的文件夹...

CRC校验详解

CRC校验即循环冗余校验(Cyclic Redundancy Check),是基于数据计算一组效验码,用于核对数据传输过程中是否被更改或传输错误。首先看两个概念,后续会用到。 模2除法:也叫模2运算,就是结果除以2后取余数。模2除法每一位除的结果不影响其它位,即不向上一位借位,所以实际…...

windows系统本地部署deepseek及webui界面

一、官网下载ollama 二、使用ollama下载deepseek r1模型 根据显存选择多少b的参数的模型 ollama run deepseek-r1:32b 三、安装conda curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe Miniconda3-latest-Windows-x86_64.exe 四、构建…...

(算法竞赛)使用广度优先搜索(BFS)解决迷宫最短路径问题

在这个充满奇思妙想的世界里&#xff0c;每一次探索都像是打开了一扇通往新世界的大门。今天&#xff0c;我们将踏上一段特别的旅程&#xff0c;去揭开那些隐藏在代码、算法、数学谜题或生活智慧背后的秘密。&#x1f389;&#x1f60a; 所以&#xff0c;系好安全带&#xff0…...

Sqoop源码修改:增加落地HDFS文件数与MapTask数量一致性检查

个人博客地址&#xff1a;Sqoop源码修改&#xff1a;增加落地HDFS文件数与MapTask数量一致性检查 | 一张假钞的真实世界 本篇是对记录一次Sqoop从MySQL导入数据到Hive问题的排查经过的补充。 Sqoop 命令通过 bin 下面的脚本调用&#xff0c;调用如下&#xff1a; exec ${HAD…...

嵌入式系统|DMA和SPI

文章目录 DMA&#xff08;直接内存访问&#xff09;DMA底层原理1. 关键组件2. 工作机制3. DMA传输模式 SPI&#xff08;串行外设接口&#xff09;SPI的基本原理SPI连接示例 DMA与SPI的共同作用 DMA&#xff08;直接内存访问&#xff09; 类型&#xff1a;DMA是一种数据传输接口…...

leetcode——将有序数组转化为二叉搜索树(java)

给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视为正确答…...

冯诺依曼结构和进程概念及其相关的内容的简单介绍

目录 ​编辑 冯诺依曼体系结构 操作系统(Operator System) 进程 引入 基本概念 描述进程-PCB task_ struct内容分类 进程 ID (PID)和查看进程 进程状态: 进程创建: 进程终止: 进程间通信 (IPC): 冯诺依曼体系结构 冯诺依曼体系结构是现代计算机的基础架构&#xf…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...