石子合并(动态规划 区间DP)+详细注释

这篇具有很好参考价值的文章主要介绍了石子合并(动态规划 区间DP)+详细注释。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原题链接  活动 - AcWing

题目

设有 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。

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

输入格式

第一行一个数 N 表示石子的堆数 N。

第二行 N 个数,表示每堆石子的质量(均不超过 1000)。

输出格式

输出一个整数,表示最小代价。

数据范围

1≤N≤300

输入样例:
4
1 3 5 2
输出样例:
22

 

解题思路:

按区间从短到长依次枚举,求区间中石子合并的最小代价并记录在f数组中 

例如  

区间长度len=2时得到

f[1][2] = 4,f[2][3] = 8,f[3][4] = 7


在区间长度len=3时根据f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1]);就可以得到

f[1][3]=f[1][2]+f[3][3]+(s[3]-s[0])=13

ps:区间长度递增的原因是区间长度长的利用到了区间长度小的数值

 

程序代码

#include<bits/stdc++.h>
const int N=1010;
int f[N][N];//表示区间 
int s[N];   //求前缀和 
int a;
using namespace std;
int main()
{
	cin>>a;
	for(int i=1;i<=a;i++)cin>>s[i]; 
	
	for(int i=1;i<=a;i++)s[i]+=s[i-1];//求前缀和,使得下标之差就是区间的元素之和 
	
	for(int len=2;len<=a;len++)//len代表区间的长度,区间的长度递增 
	{
		for(int i=1;i+len-1<=a;i++)//例如,i=1,len=2时 i+len-1=2,1到2即表示区间长度为2
		{
			int l=i,r=i+len-1;
			f[l][r]=0x3f3f3f3f;
			
			for(int k=l;k<r;k++)//k用来切割区间 
			{
				f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1]);
				//区间从左到右依次分割求理想的最小值 
			}
			//s[r]-s[l-1]为最后一下合并区间内的石子需要的体力为区间内所有石子的和 
		}
	}
	cout<<f[1][a];//输出1到a区间的最小和,就是答案 
}

 文章来源地址https://www.toymoban.com/news/detail-574900.html

到了这里,关于石子合并(动态规划 区间DP)+详细注释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 石子合并问题(动态规划)

    石子合并问题是一个经典的动态规划问题,应用了最优子结构和重复子问题的思想。 (1)有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成 (动态规划)O(n^3) 设dp[i][j]表示将i至j之

    2024年02月06日
    浏览(33)
  • 【动态规划】之石子合并问题

    在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请设计一个程序,计算出将N堆石子合并成一堆的最小得分和最大得分。 我们对n的取值逐步分析 当n=1时,没有进

    2024年04月28日
    浏览(27)
  • 租用游艇问题 石子合并问题 动态规划实验

    实验名称:                动态规划                          一、实验预习 1、实验目的 1. 理解并掌握动态规划方法的设计思想; 2. 提高应用动态规划方法解决问题和设计算法的能力; 3. 通过编程实现租用游艇问题和石子合并问题,进一步理解动态规划方

    2024年02月07日
    浏览(35)
  • C++动态规划经典案例解析之合并石子

    区间类型问题,指求一个数列中某一段区间的值,包括求和、最值等简单或复杂问题。此类问题也适用于动态规划思想。 如 前缀和 就是极简单的区间问题。如有如下数组: 现给定区间信息 [3,6] ,求区间内所有数字相加结果。即求如下图位置数字之和。 Tips: 区间至少包括

    2024年02月11日
    浏览(30)
  • 区间dp(动态规划)

    动态规划(dp)是一种通过将问题分解为子问题,并利用已解决的子问题的解来求解原问题的方法。适用于具有重叠子问题和最优子结构性质的优化问题。通过定义状态和状态转移方程,动态规划可以在避免重复计算的同时找到问题的最优解,是一种高效的求解方法,常用于

    2024年02月15日
    浏览(30)
  • 动态规划——区间DP 学习笔记

    不含四边形不等式优化。 线性动态规划的局限性在于,它只能顺推或倒退,而不能有子区间依赖的问题。 区间动态规划是线性动态规划的扩展,它将问题划分为若干个子区间,并通过定义状态和状态转移方程来求解每个子区间的最优解,最终得到整个区间的最优解。 区间动

    2024年02月08日
    浏览(32)
  • 动态规划系列 | 一文搞定区间DP

    区间 DP 可以用于解决一些涉及到区间合并或分割的问题。区间 DP 通常有以下三个特点: 合并(分割) :将两个或多个部分进行整合,或者反过来将一个区间分解成多个部分。 特征 :能将问题分解为能两两合并的形式。 求解 :对整个问题设最优解,枚举合并点,将问题分

    2024年02月02日
    浏览(34)
  • acwing算法基础之动态规划--线性DP和区间DP

    线性DP:状态转移表达式存在明显的线性关系。 区间DP:与顺序有关,状态与区间有关。 题目1 :数字三角形。 解题思路:直接DP即可, f[i][j] 可以来自 f[i-1][j] + a[i][j] 和 f[i-1][j-1] + a[i][j] ,注意 f[i-1][j] 不存在的情况(最后一个点)和 f[i-1][j-1] 不存在的情况(第一个点)。

    2024年02月04日
    浏览(40)
  • 【动态规划】LeetCode 312. 戳气球 --区间DP问题

      Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接       我会一直往里填充内容哒! 🌈LeetCode专栏:专栏链接       目前在刷初级算法的LeetBook 。若每日一题当中有力所能

    2023年04月16日
    浏览(30)
  • 蓝桥杯备赛之动态规划篇——涂色问题(区间DP)

    2023第十四届蓝桥杯模拟赛第二期个人题解(Java实现) 2023第十四届蓝桥杯模拟赛第三期个人题解(Java实现) 蓝桥杯备赛之动态规划篇——背包问题 蓝桥杯真题——单词分析(Java实现) 😘😘 哈喽,大家好!这里是蓝桥杯系列文章的动态规划章节🔥🔥,今天要讲解的是区

    2024年01月23日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包