我是靠谱客的博主 高兴鞋垫,最近开发中收集的这篇文章主要介绍石子合并问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题描述:在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。

输入文件:

input.txt

4

4 4 5 9

输出文件:

output.txt

43

54


算法思路:仿照动态规划求解矩阵连乘问题的方式,与矩阵连乘问题不同的是,它的结构是一个环。

#include<iostream>
const int N = 64;
int sum[N];
int arr[N];
int dp_min[N][N];
int dp_max[N][N];
//求最小值
int min(int lhs, int rhs){
return lhs < rhs ? lhs : rhs;
}
//求最大值
int max(int lhs, int rhs){
return lhs > rhs ? lhs : rhs;
}
void computer(int arr[], int arr_length, int& min_num, int& max_num){
for (int i = 0; i < arr_length; i++){
dp_min[i][i] = 0;
}
for (int r = 1; r < arr_length; r++){
for (int i = 0; i < arr_length; i++){
int j = (i + r) % arr_length;
int tm;
if (j > i){
tm = sum[j] - (i > 0 ? sum[i - 1] : 0);
}
else{
tm = sum[arr_length - 1] - sum[i - 1] + sum[j];
}
dp_min[i][j] = dp_min[i][(i + 1) % arr_length] + dp_min[(i + 2) % arr_length][j] + tm;
dp_max[i][j] = dp_max[i][(i + 1) % arr_length] + dp_max[(i + 2) % arr_length][j] + tm;
for (int k = i, index = i ; index < i + r; index++){
dp_min[i][j] = min(dp_min[i][j], dp_min[i][k] + dp_min[(k + 1) % arr_length][j] + tm);
dp_max[i][j] = max(dp_max[i][j], dp_max[i][k] + dp_max[(k + 1) % arr_length][j] + tm);
k = (k + 1) % arr_length;
}
}
}
min_num = dp_min[0][arr_length - 1];
max_num = dp_max[0][arr_length - 1];
for (int i = 0; i < arr_length; i++){
min_num = min(min_num, dp_min[i][(i + arr_length - 1) % arr_length]);
max_num = max(max_num, dp_max[i][(i + arr_length - 1) % arr_length]);
}
}
int main(void){
int n = -1;
int min_num, max_num;
std::cin >> n;
for (int count = 0; count < n; count++){
std::cin >> arr[count];
sum[0] = arr[0];
for (int i = 1; i < n; i++){
sum[i] = sum[i - 1] + arr[i];
}
}
computer(arr, n, min_num, max_num);
std::cout << min_num << "n" << max_num << std::endl;
return 0;
}




最后

以上就是高兴鞋垫为你收集整理的石子合并问题的全部内容,希望文章能够帮你解决石子合并问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部