任务描述
沿着河岸摆放 N
堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2
堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。 例如:4
堆石子4,5,9,4
,可以按(((4,5),9),4)
合并。
- 第一次合并得分是
9
分,合并之后石子堆是9,9,4
- 第二次合并得分是
18
分,合并之后石子堆是18,4
- 第三次合并得分是
22
分,合并之后石子堆是22
- 三次合并总得分
49
试设计出一个算法,计算出将 N
堆石子合并成 1
堆的最小得分和最大得分。
测试说明
输入格式
数据的第 1
行是正整数 N
,表示有N
堆石子。
第 2
行有 N
个整数,第i
个整数 ai
表示第i
堆石子的个数。
输入格式
输出共 2
行,第 1
行为最小得分,第 2
行为最大得分。
样例输入
4
4
5
9
4
样例输出
44
54
提示
1≤N≤100
,0≤ai≤20
。
相关知识
编程要求
根据提示,在右侧编辑器编写函数,输出石子合并问题的最小得分和最大得分。
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
vector<vector<int>> minScore; // 存储最小得分
vector<vector<int>> maxScore; // 存储最大得分
vector<int> stones; // 存储石子堆的石子数
// 计算最小得分
int getMinScore(int start, int end) {
if (start == end) {
return 0; // 如果只有一堆石子,返回0得分
}
if (minScore[start][end] != -1) {
return minScore[start][end]; // 如果已经计算过,直接返回结果
}
int minVal = INT_MAX; // 最小得分的初始值设为最大整数
// 遍历每一种合并方式,选取最小得分
for (int i = start; i < end; i++) {
int score = getMinScore(start, i) + getMinScore(i + 1, end) + stones[start] * stones[i + 1] * stones[end + 1];
if (score < minVal) {
minVal = score;
}
}
minScore[start][end] = minVal; // 存储最小得分
return minVal;
}
// 计算最大得分
int getMaxScore(int start, int end) {
if (start == end) {
return 0; // 如果只有一堆石子,返回0得分
}
if (maxScore[start][end] != -1) {
return maxScore[start][end]; // 如果已经计算过,直接返回结果
}
int maxVal = 0; // 最大得分的初始值设为0
// 遍历每一种合并方式,选取最大得分
for (int i = start; i < end; i++) {
int score = getMaxScore(start, i) + getMaxScore(i + 1, end) + stones[start] * stones[i + 1] * stones[end + 1];
if (score > maxVal) {
maxVal = score;
}
}
maxScore[start][end] = maxVal; // 存储最大得分
return maxVal;
}
int main() {
int N; // 石子堆的数量
cout << "请输入石子堆的数量 N:";
cin >> N;
// 初始化石子堆
stones.resize(N + 1);
minScore.resize(N, vector<int>(N, -1));
maxScore.resize(N, vector<int>(N, -1));
cout << "请依次输入每堆石子的数量:" << endl;
for (int i = 0; i < N; i++) {
cin >> stones[i];
}
// 计算最小得分和最大得分
int minResult = getMinScore(0, N - 1);
int maxResult = getMaxScore(0, N - 1);
cout << "将 " << N << " 堆石子合并成 1 堆的最小得分为:" << minResult << endl;
cout << "将 " << N << " 堆石子合并成 1 堆的最大得分为:" << maxResult << endl;
return 0;
}