首页 > 其他分享 >[区间dp]合并石子升级版

[区间dp]合并石子升级版

时间:2024-10-15 10:49:47浏览次数:8  
标签:int sum 石子 long k2 k1 升级版 dp

题目描述

还记得经典题石子合并吗?现在小 Y Y Y 将题目加强啦!
在一个圆形操场的四周摆放着 n n n 堆石子,现要将石子有次序地合并成一堆。规定每次只能选取相邻的三堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
编一程序,读入石子堆数 n n n 及每堆的石子数。选择一种合并石子的方案,使得做 ( n − 1 ) / 2 (n − 1) / 2 (n−1)/2 次合并,得分的总和最小。

输入格式

第 1 1 1 行 1 1 1 个数,表示石子堆数。
第 2 2 2 行是顺序排列的各堆石子数( ≤ 1000 \le 1000 ≤1000),每两个数之间用空格分隔。

输出格式

输出合并的最小得分。

样例

样例输入1:

5
1 2 3 4 5

样例输出1:

21

样例1解释:
先合并 ( 1 , 2 , 3 ) (1, 2, 3) (1,2,3),再合并 ( 6 , 4 , 5 ) (6, 4, 5) (6,4,5)。

数据范围

对于 20 % 20\% 20% 的数据, n = 5 n = 5 n=5。
对于 60 % 60\% 60% 的数据, n ≤ 80 n \le 80 n≤80。
对于 100 % 100\% 100% 的数据, 3 ≤ n ≤ 400 3 \le n \le 400 3≤n≤400。

题解

由于是圆形的,所以需要破环为链,这里我直接复制一份到后面即可。

对于 20 % 20\% 20% 的数据,先合并三堆后,只剩下三堆,直接枚举即可。

对于 60 % 60\% 60% 的数据,和合并石子差不多,依然是 区间dp
d p i , j = m i n { d p i , k 1 + d p k 1 + 1 , k 2 + d p k 2 + 1 , j + s u m j − s u m i − 1 } dp_{i, j} = min\{dp_{i, k1} + dp_{k1 + 1, k2} + dp_{k2 + 1, j} + sum_j - sum_{i - 1}\} dpi,j​=min{dpi,k1​+dpk1+1,k2​+dpk2+1,j​+sumj​−sumi−1​}。
枚举长度和左端点,计算右端点,枚举两个断点进行转移。
复杂度为 Θ ( n 4 ) \Theta(n^4) Θ(n4)。

如果这道题你写的 60 60 60 分代码是 20 20 20 分,可以试一下以下数据:
输入

7
1 3 4 2 5 1 5

输出

37

解释
先合并 ( 1 , 5 , 1 ) (1, 5, 1) (1,5,1),再合并 ( 3 , 4 , 2 ) (3, 4, 2) (3,4,2),最后合并 ( 9 , 5 , 7 ) (9, 5, 7) (9,5,7)。

int f[810][810];//dp
int sum[810];//前缀和
int main(){
	输入
	//破环为链
	for(int i = 1; i <= n; ++ i){
		a[i + n] = a[i];
	}
	//初始化
	for(int i = 1; i <= 2 * n; ++ i){
		f[i][i] = 0;
		f[i][i + 1] = 0x3f3f3f3f;
		f[i][i + 2] = a[i] + a[i + 1] + a[i + 2];
		sum[i] = sum[i - 1] + a[i];
	}
	//转移
	for(int l = 4; l <= n; ++ l){//长度
		for(int i = 1; i <= 2 * n - l; ++ i){//左端点
			int j = i + l - 1;//[i, j]
			//[i, k1] + [k1 + 1, k2] + [k2 + 1, j]
			f[i][j] = 0x3f3f3f3f;
			//枚举断点
			for(int k1 = i; k1 <= j; ++ k1){
				for(int k2 = k1; k2 <= j; ++ k2){
					f[i][j] = min((long long)f[i][k1] + f[k1 + 1][k2] + f[k2 + 1][j] + sum[j] - sum[i - 1], (long long)f[i][j]);
				}
			}
		}
	}
	//统计答案
	int ans = 0x3f3f3f3f;
	for(int i = 1; i <= n; ++ i){
		ans = min(ans, f[i][n + i - 1]);
	} 
} 

对于 100 % 100\% 100% 的数据,时间复杂度肯定超了。

这时我们考虑原版合并石子问题,只需要枚举一个断点,而当前枚举了两个断点。
将两个断点想成先断一处,再断一处。
先断就相当于原版合并石子问题,再断一处就从先断处理出的值和另外一边的值转移即可。
复杂度为 Θ ( n 3 ) \Theta(n^3) Θ(n3)。

int main(){
	输入,破环为链
	//预处理
	for(int i = 1; i <= 2 * n; ++ i){
		f[i][i] = 0;
		f[i][i + 1] = 1e16;
		sum[i] = sum[i - 1] + a[i];
	}
	for(int l = 3; l <= n; ++ l){
		for(int i = 1; i <= 2 * n - l; ++ i){
			int j = i + l - 1;
			f2[i][j] = f[i][j] = 1e16;
			//预处理先断
			for(int k1 = i; k1 < j; ++ k1){
				f2[i][j] = min((long long)f[i][k1] + f[k1 + 1][j], (long long)f2[i][j]);
			}
			//后断
			for(int k2 = i; k2 < j; ++ k2){
				f[i][j] = min((long long)f2[i][k2] + f[k2 + 1][j] + sum[j] - sum[i - 1], (long long)f[i][j]);
			}
		}
	}
	统计答案
} 

标签:int,sum,石子,long,k2,k1,升级版,dp
From: https://blog.csdn.net/m0_64542522/article/details/142935230

相关文章

  • 在Ubuntu上使用LAMP安装WordPress
    在开始之前我们要先查看ssh服务的状态,确保其能远程连接。一、安装并设定ApacheWeb服务器设置LAMP的第一步是安装和配置Apache服务器。首先,我们需要在系统上更新并升级包列表,并将包升级到最新版本。在您的SSH客户端上使用以下命令执行此操作:​sudoaptupdate-......
  • UDP协议
    UDP概述用户数据报协议UDP只在IP的数据报服务之上增加了很少一点的功能,即复用、分用以及差错检测功能。UDP的主要特点是:UDP是无连接的,即发送数据之前不需要建立连接,减少了开销和发送数据之前的时延UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态......
  • 牛客AB33.相差不超过k的最多数 (滑动窗口) 牛客.DP最长公共子序列牛客.春游主持人调度
    目录牛客AB33.相差不超过k的最多数 (滑动窗口) 牛客.DP最长公共子序列牛客.春游主持人调度(二)牛客AB33.相差不超过k的最多数 (滑动窗口) 和之前那个空调吹风属于一道题的类型,当然滑动窗口,最大值-最小值,然后<=p即可也可以双指针来取寻找最大值和最小值impor......
  • scientifically practice DP
    Iunderstandyourfrustration,andit'sacommonfeelingwhentacklingcomplexproblemslikethis.Findingtheseinsightsoftencomesdowntoacombinationofexperience,practice,andasystematicapproachtoproblem-solving.Here'showyoucan......
  • HivisionIDPhotos 开源精美证件照
    马上就该考研啦,还在用某x、某xxx做证件照吗?也就用一次还得花几块钱买个会员,别当冤大头啦!最近1个月一个颠覆性的开源产品稳站GitHub榜前三,没错!他就是hivisionidphotos。博士团队开源项目,只能说太强!项目链接:https://github.com/Zeyi-Lin/HivisionIDPhotos短短1个月,竟然有1......
  • linux 操作系统下的dpkg 命令介绍和使用案例
    dpkg命令介绍dpkg是Debian及其衍生版(如Ubuntu)中用于管理软件包的底层工具。它的全称为“DebianPackage”,主要用于安装、删除、构建和管理以.deb格式存在的软件包。虽然dpkg功能强大,但它不会自动处理软件包之间的依赖关系,因此在使用时需谨慎主要功能安装软件包:使用dpkg-i......
  • 一键生成证件照的开源利器:HivisionIDPhotos使用教程
    HivisionIDPhotos使用教程:一键生成证件照的开源利器HivisionIDPhotos 是一款开源的、轻量级且高效的AI工具,专注于证件照的自动生成。通过这一工具,用户只需上传一张自拍或其他照片,便能快速生成标准尺寸的证件照,免去前往照相馆的麻烦。它利用先进的图像处理技术,如智能抠图......
  • 【Oracle DB故障分享】分享一次由于SGA设置太小导致的DP备份失败
    Listitem今天给客户做Oracle例行数据库健康巡检,过程中检出一些备份异常,分享如下。排查问题:打开DP备份软件,随即弹出如下提示:登录DP,查看备份情况:发现从10/6开始,DP备份就没有完全成功,部分文件备份失败:OracleRecoveryBackupCatalog“Oracle8”一直备份失败:查看DP日......
  • 浅谈Java之UDP通信
    一、基本介绍        Java提供了用于处理UDP(用户数据报协议)的类和方法。UDP是一种无连接的网络协议,它允许发送端和接收端之间无需建立连接即可发送数据。在Java中,你可以使用java.net包中的DatagramSocket和DatagramPacket类来实现UDP通信。二、简单用法以下是使用......
  • P6748 Fallen Lord [树形DP]
    P6748FallenLordDescription给定\(n\)个节点的树,每个点有点权\(a_i\),求构造一组边权,使得每个点连接的边的边权的中位数不超过其点权,且每条边权不超过给定的\(m\),输出边权之和的最大值。一个升序序列\(A=\{A_1,A_2,A_3...A_n\}\)的中位数定义为\(A_{\lfloorn/2\rfloor......