【DP入门】石子合并(一)

求解石子合并问题(选择dp循环的顺序) 实验目的: 练习动态规划 实验内容: 有n堆石子排成一排,每堆石子有一定的数量,现要将n堆石子合并成为一堆,合并只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和, 经过n-1次合并后成为一堆,求出总代价的最小值。 输入描述:有多组测试数据,输入到文件结束。每组测试数据的第1行有一个整数n, 表示有n堆石子,接下来的一行有n(0<n<200)个数,分别表示这n堆石子的数目,用空格隔开。 输出描述:输出总代价的最小值,占单独的一行。 输入样例: 3 1 2 3 7 13 7 8 阅读详情

题目来自nyist737题,如下:

描述

有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
输入
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出

输出总代价的最小值,占单独的一行


分析:

很容易想到哈夫曼编码,但是此处要求只能相邻两堆石子合并,所以哈夫曼的贪心策略不方便实施。DP解法:近似穷举,先考虑两两合并,记录最优中间下标k,可以近似想象成加木板,比如1、2合并就是在1-2中加一个木板k=1,这样逐步记录下最优的合并方案。然后三三合并,四四合并,直到最后N堆石子合并,从下到上构建出结果,时间复杂度为O(n³)。

同样思想的是矩阵链乘,也是相邻两两合并,直到剩下一个。

平行四边形优化:对于递推式 dp[i][j] = min (dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]) 其最优的k值一定在  s[i][j-1]至s[i+1][j]中,其中s[i][j]为第i到j这两堆(因为已经逐层合并了 所以是两堆)取最优解时的k值。具体证明详见百度Google。可以优化到O(n²);


代码如下:

#include <stdio.h>
#include <string.h>
int stone[205];
int s[205][205];
int dp[205][205];
int sum[205];
int main() 
{
	int N;
	int i,j,len,k,temp;
	while(scanf("%d",&N) != EOF)
	{
		for(i = 0;i < N;i++)
		{
			scanf("%d",&(stone[i]));
			s[i][i] = i;
			dp[i][i] = 0;
		}
		sum[0] = stone[0];
		for(i = 1;i < N;i++)	
			sum[i] = sum[i-1] + stone[i];
		for(len = 2;len <= N;len++)
		{
			for(i = 0;i < N-len+1;i++)
			{
				j = len+i-1;
				int t_k ;
				temp = 100000;//INF即可
				for(t_k = s[i][j-1];t_k <=s[i+1][j] ;t_k++)
				{
					if(temp > dp[i][t_k] + dp[t_k+1][j]+sum[j]-sum[i]+stone[i])
					{
						temp = dp[i][t_k] +dp[t_k+1][j] + sum[j] - sum[i]+stone[i];
						k = t_k; 
					}
					s[i][j] = k;
					dp[i][j] = temp;
				}
			}
		}
		printf("%d\n",dp[0][N-1]);
	}
	return 0;
}

DP的很多题目都有相似之处,要先把经典题目刷完,然后在此之上扩展,锻炼DP思想,才能合理利用。
合并石子 (区间DP) 1274:【例9.18】合并石子 【题目描述】 在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。 计算出将N堆石子合并成一堆的最小得分。 【输入】 第一行为一个正整数N (2≤N≤100); 以下N行,每行一个正整数,小于10000,分别表示第i堆石子的个数(1≤i≤N)。 【输出】 一个正整数,即最... 阅读详情

相关推荐

石子合并(区间dp)

设有N堆石子排成一排,其编号为1,2,3,…,N。 每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆。 每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。 例如有4堆石子分别为 1 3 5 2, 我们可以先合并1、2堆,代价为4,得到4 5 2, 又合并 1,2堆,代价...

Mr_Kingk的博客 633

区间dp模板 + 2057 - 合并石子 ---区间dp

区间dp

weixin_73739312的博客 126

区间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,得

HelloACM_ICPC的博客 499

Acwing 282. 石子合并

注:当区间长度为1时(即len = 1),区间不需要合并,代价是0,因为f是全局数组,所以len可以从2开始循环。f[i][j]表示将所有第i堆石子到第j堆石子合并成一堆石子的合并方式,这些方式中代价的最小值。每一类的最小代价 = 左边的最小代价 + 右边的最小代价 + 最后一步的代价。我们可以以最后一次合并的分界线来划分集合。最后对每一类的最小代价取最小值。

青衫客36的博客 308

石子合并【DP】

题目: 在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请设计一个程序,计算出将N堆石子合并成一堆的最小得分。 输入 每组数据第1行为一个正整数N(2&lt;=N&lt;=100),以下N行,每行一个正整数,小于10000,分别表示第i堆石子的个数(1&lt;=i&lt;=N)。 输出 对于...

还有一年 897

Android加密开发实战:Spongy Castle集成与国密算法应用指南

在移动应用开发中,数据加密是保障用户隐私和信息安全的基石。其原理基于密码学算法,通过对数据进行编码转换,确保即使数据被截获也无法被未授权方解读。这项技术的核心价值在于为敏感信息提供机密性、完整性和身份验证,广泛应用于用户登录、本地存储、网络通信等场景。对于Android开发者而言,系统自带的加密功能有时无法满足需求,特别是涉及国密算法或更丰富算法套件时。本文聚焦于Spongy Castle这一专为Android定制的加密库,它有效解决了与系统内置Bouncy Castle的兼容性问题,并提供了对SM4等国密

weixin_27722377的博客 309

【基础算法】石子合并-版本1

此题主要是用dp求出每个范围的最小价值,再用递归输出。 时间限制: 1 Sec 内存限制: 64 MB 题目描述 设有n堆石子排成一排,其编号为1,2,3,…,n。每堆石子有一定的数量,例如: 13 7 8 16 21 4 18 现要将n堆石子归并为一堆。归并的过程为每次只能将相邻的两堆石子堆成一堆,这样经过n-1次归并之后最后成为一堆。对于上面的7堆石子,可以有多种方法归并成一堆。其中的...

TL的博客 1026

用Keil5给CH552G编程:手把手配置8051开发环境+LED闪烁实战

本文详细介绍了如何使用Keil5为CH552G单片机配置8051开发环境,并完成LED闪烁实战。从获取必要软件、安装WCH器件库到创建工程、编写程序及烧录,手把手指导开发者避开常见陷阱,特别适合从STC转向CH552G的开发者。

weixin_30733003的博客 539

经典区间dp-石子合并

经典区间dp-石子合并 题目描述: 有n堆石子排成一排,每堆石子有一定的数量,将n堆石子合并成一堆。合并的规则是每次只能合并相邻的两堆石子,合并的花费为这两堆石子的总数。石子经过n-1次合并后成为一堆,求总的最小花费。 输入:有多组测试数据,输入到文件结束。每组测试数据的第1行有一个整数n,表示有n堆石子,n<250。接下来的一行有n个数,分别表示这n堆石子的数目。每堆石子至少一颗,最多10...

qq_44624316的博客 652

SSD性能测试进阶:用fio的io_uring引擎榨干你的NVMe硬盘

本文深入探讨了如何利用fio的io_uring引擎对NVMe SSD进行深度性能测试。通过对比传统libaio引擎,详解了io_uring低开销、高并发的优势。文章提供了从测试矩阵设计、队列深度分析到写入放大观察和尾延迟可视化的完整进阶方法,并附有实战案例与脚本,旨在帮助用户科学压榨NVMe硬盘的极限性能,获取更真实的评估数据。

weixin_29247219的博客 328

逆向工程实战:从零解析微信PC版协议,并用开源代码构建你的私有化接口

本文详细解析了微信PC版的通信协议架构,从逆向工程基础到网络流量捕获、关键函数定位与HOOK技术实践,最终通过开源代码构建私有化接口。文章重点介绍了协议特征分析、HOOK技术应用以及安全实践,帮助开发者深入理解企业级通信协议的设计逻辑和安全机制。

weixin_30496999的博客 393

NYOJ737:石子合并(一)(区间dp入门)

石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述    有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。 输入有多组测试数据,输入到文件结束。 每组测试数据第一行有一个整

junior19的博客 344

FFTW3库在Windows中的安装和使用

Windows 32位平台下载:FFTW Installation on Windows。

weixin_45397344的博客 951

NYoj - 737 - 石子合并(一)最详细的详解(区间DP入门题)

石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述    有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。 输入有多组测试数据,输入到文件结束。 每组测试数据第一行有一个整

K键盘里的青春K 4125

电子电器架构 -- 汽车零部件DV试验与PV试验的定义及关键差异

电子电器架构 -- 汽车零部件DV试验与PV试验的定义及关键差异

Soly_kun的博客 735

【数据集】中国大气污染物数据集CHAP(1km空间分辨率)-韦晶团队

中国大气污染物数据集CHAP(1km空间分辨率)-韦晶团队

WW、forever的博客 2600

『经典DP入门』三种石子合并问题

『问题概述』 石子合并问题是经典的DP问题。首先它有如下3种题型: 1)有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成 ...

Miserable_ccf的博客 2905

数仓解惑:数据仓库常见建模方法与大数据领域建模实例综述

为什么需要数据建模? 为什么要进行数据仓库建模? 随着DT时代互联网、智能设备等信息技术的发展,数据开始井喷式的增长,如何讲这些数据进行有序、有结构地分类组织存储是我们面临的一个挑战。 如果把数据看作图书馆里的书,我们希望看到它们在书架上分门别类地放置,而不是乱糟糟的 大数据的数仓建模是通过建模的方法更好的组织、存储数据,以便在 性能、成本、效率和数据质量之间找到最佳平衡点。一般主要从下面四点考虑 ...

云祁QI 5850

区间DP石子合并

区间dp也符合动态规划的三阶段,但是也有自己特殊的地方,先来看一下总结,然后再在后面的题目中体验。第一阶段定义dp数组(1)缩小规模。在区间dp里,规模是区间的大小。当区间规模大小固定时,而不同的左右端点所产生的区间又是不一样的,所以需要两个维度来表示区间的左右端点。(2)考虑限制。(3)写出dp数组。这里的转移要注意,一般背包DP,线性DP,对于dp[i]是从dp[i-1]转移的。而区间DP,对于dplrdp[l][r]dplr大多数是从dpl1r。

qq_53237241的博客 1446

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

[区间dp]合并石子

区间dp 合并石子 破环为链 前缀和

m0_64542522的博客 806

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

合并石子DP详解(C++)

合并石子DP(C++) 问题描述   在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数。求把所有石子合并成一堆的最小花费。 输入格式: 输入第一行包含一个整数n,表示石子的堆数。 接下来一行,包含n个整数,按顺序给出每堆石子的大小 。 输出格式:   输出一个整数,表示合并的最小花费。 样例输入 5 1 2 3 4 5 样...

qq_45491896的博客 3239

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

动态规划:合并石子(区间DP)

摘要 本文介绍了使用动态规划解决石子合并问题的区间DP方法。问题要求每次只能合并相邻的两堆石子,目标是找出最小合并成本。采用二维状态数组f[i][j]表示从i到j石子的最小合并成本,通过枚举区间长度、起点和分界点,利用前缀和优化计算。具体实现时,先预处理前缀和数组,然后按区间长度递增的顺序进行状态转移,最终输出f[1][n]作为结果。该方法时间复杂度为O(n³),适用于典型的区间DP问题。

Zephyrtoria的博客 1000

【DP】石子合并

1 线形石子合并 参考题目 https://www.acwing.com/problem/content/284/ 题目要求最小代价 大致思路为: 有n组石头排成一条线, 规定把第i组和第i组合并(自己合并自己),代价为0 1.求所有相邻的两堆石头合并的代价 2.求所有相邻的三堆石头合并的代价,之前求出的两堆石头合并的代价可以作为前提 3.求所有相邻的四堆石头合并的代价,之前求出的两堆石头合并的代价和三堆石头合并的代价都可以作为前提 … n-1.求相邻的n堆石头合并的代价,之前求出的【2,n-1】堆石头合并

wldcmzy的博客 362

石子合并——最经典的dp问题

石子合并三大题型 任意两堆石子合并,直接手写一个小根堆,每次取前面两个相加,得到的值继续放入优先队列中,直到里面只有一个元素就输出 只能合并相邻两堆石子,这就类似于矩阵连乘(传送门),不过还是有一些差别 在2的基础上,这些石子形成一个环形,这又是一种新的题型 今天记录的是第二种——区间dp 题目描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位...

少年白马 1224

线性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;

dont worry about it的博客 3万+
上一篇: 【DP入门】聪明的kk
下一篇: 【图论入门】吝啬的国度
Ampersand
博客等级 码龄10年 6粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值