当前位置:首页 > 题解目录 > 正文内容

【题解】石子合并

亿万年的星光5个月前 (05-30)题解目录368

【题目描述】

在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。

设计一个程序,计算出将N堆石子合并成一堆的最小得分。

【输入描述】

第一行为一个正整数N (2≤N≤100);

以下N行,每行一个正整数,小于10000,分别表示第i堆石子的个数(1≤i≤N)。

【输出描述】

为一个正整数,即最小得分。

【样例输入】

7
13
7
8
16
21
4
18

【样例输出】

239



【题目分析】

1.定义状态:

设 dp[i][j] 表示合并第 i 堆到第 j 堆石子的最小得分。

为了方便计算区间和,预处理一个前缀和数组 sum,其中 sum[i] 表示前 i 堆石子的总数。


2.状态转移方程:

对于区间 [i, j],枚举最后一次合并的分割点 k(i ≤ k < j),将区间分成 [i, k] 和 [k+1, j]。

合并这两部分的得分为 sum[j] - sum[i-1](即区间 [i, j] 的石子总数)。

状态转移方程为:

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

3.初始化:

单个石堆不需要合并,因此 dp[i][i] = 0。

其他 dp[i][j] 初始化为一个较大值(如 INT_MAX)。


4.计算顺序:

按区间长度从小到大计算,因为长区间的结果依赖于短区间。



【参考答案】

#include <iostream>
#include <climits>
using namespace std;

const int MAX_N = 100;  // 最大石子堆数

int main() {
	int N;
	cin >> N;
	int stones[MAX_N + 1] = {0};  // 石子堆,从1开始编号
	int sum[MAX_N + 1] = {0};     // 前缀和数组
	for (int i = 1; i <= N; i++) {
		cin >> stones[i];
		sum[i] = sum[i - 1] + stones[i];
	}

	// DP表,dp[i][j]表示合并i到j堆的最小得分
	int dp[MAX_N + 1][MAX_N + 1] = {0};

	// 初始化:单个石堆不需要合并,得分为0
	for (int i = 1; i <= N; i++) {
		dp[i][i] = 0;
	}

	// 按区间长度从小到大计算
	for (int len = 2; len <= N; len++) {      // 区间长度
		for (int i = 1; i + len - 1 <= N; i++) {  // 区间起点
			int j = i + len - 1;              // 区间终点
			dp[i][j] = INT_MAX;
			for (int k = i; k < j; k++) {     // 枚举分割点
				dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]);
			}
		}
	}

	cout << dp[1][N] << endl;
	return 0;
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【题解】感应门

【题目描述】感应门会在有人经过的时候自动打开,冷却d 秒后自动关闭。如果有人在感应门打开的状态下通过,那么冷却时间会重置,重新冷却d秒后再关闭。在一段时间内,有 n个人陆续通过了感应门,他们...

【题解】滚动的榜单

【题目描述】某比赛的成绩,是依次出现的,而每个选手的成绩依次公布的时候,榜单都会刷新一遍,就能看到该选手在当前榜单加入时,所在的名次。下面给出了榜单选手的成绩,这里想知道,对于某个选手,求该选手在加入...

【题解】光荣的梦想

【题目描述】Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平...

【题解】尼科彻斯定理

【题目描述】 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。【输入描述】任一正整数【输出描述】该数的立方分解为一串连续奇数的和【样例输入】13【样例输出】13*13*...

求Π的值

【题目描述】根据公式:arctanx(x)=x−x^3/3+x^5/5−x^7/7+…和π=6arctanx(1/√3).定义函数arctanx(x),求当最后一项小于10^(−6)时π的值。【输入描...

【题解】2019 T2 公交换乘

【题目描述】著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案:1、在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠...