问题描述:在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
试设计一个算法。
- 选择一种合并石子的方案,使得做 n-1 次合并得分总和最大。
- 选择一种合并石子的方案,使得做 n−1 次合并得分总和最小。
算法设计:对于给定n堆石子,计算合并成一堆的最小得分和最大得分。
数据输入:
第一行是正整数n(1<=n<=200),表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。
输出格式
输出共两行:
第一行为合并得分总和最小值,
第二行为合并得分总和最大值。
输入:
4
4 5 9 4
输出:
43
54
代码:
问题不具有局部最优代替整体最优,不能用贪心法。
但是可以分为子问题,选择不同的堆进行合并。
动态规划——状态转移方程——找分割点
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n;//n堆石子
const int N=410;
int amax[N][N];
int amin[N][N];
int sum[N];//前缀和
int a[N];
const int MAX=0x3f3f3f3f;
int main()
{
cin>>n;
mems