石子合并
题目描述
将n堆石子绕圆形操场排放,现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分。
请编写一个程序,读入堆数n及每堆的石子数,并进行如下计算:
请编写一个程序,读入堆数n及每堆的石子数,并进行如下计算:
- 选择一种合并石子的方案,使得做n-1次合并得分总和最大。
- 选择一种合并石子的方案,使得做n-1次合并得分总和最小。
输入描述:
输入第一行一个整数n,表示有n堆石子。
第二行n个整数,表示每堆石子的数量。
输出描述:
第一行为合并得分总和最小值,
第二行为合并得分总和最大值。
输入
4 4 5 9 4
输出
43 54
#include<bits/stdc++.h> using namespace std; const int N = 4e2 + 7; int a[N], n; int mi[N][N], mx[N][N], sum[N]; int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i], a[i + n] = a[i]; for (int i = 1; i <= 2 * n; i++) sum[i] = sum[i - 1] + a[i]; memset(mi, 0x3f, sizeof(mi)); memset(mx, 0, sizeof(mx)); for (int i = 1; i <= 2 * n; i++) mi[i][i] = 0, mx[i][i] = 0; for (int len = 2; len <= n; len++) { for (int l = 1; l <= 2 * n - len + 1; l++) { int r = l + len - 1;//[l, r] for (int k = l; k < r; k++) { mi[l][r] = min(mi[l][r], mi[l][k] + mi[k + 1][r] + sum[r] - sum[l - 1]); mx[l][r] = max(mx[l][r], mx[l][k] + mx[k + 1][r] + sum[r] - sum[l - 1]); } } } int least = 0x3f3f3f3f, most = 0; for (int i = 1; i <= n; i++) { least = min(least, mi[i][i + n - 1]); most = max(most, mx[i][n + i - 1]); } cout << least << endl; cout << most << endl; return 0; }

浙公网安备 33010602011771号