'Problem Description:
around a circular playground placed stones piled n. Stone is to have the order to merge into a pile. Prescribed a time
can choose two adjacent pile into a new pile of stones, a pile of stones and a few new record for the combined score. Test design one
algorithms, to calculate the n combined into a pile of stones piled minimum score and maximum score.
'Programming tasks:
For a given n gravel pile, merge into a pile programmed computing the minimum and maximum score score.
'Input Data:
provided by the input data file input.txt. The first line of the file is a positive integer n, 1 £ n £ 100, n represents stones piled there.
The second row has a number of n, respectively, represent the number of each pile of stones.
'Output Results:
At the end of run, outputs the calculation result to the file output.txt. The number of rows in the first file is the smallest available
partition; the second number of rows is the maximum score;.
Sample output file input file Example
input.txt output.txt
. 4
. 4. 5. 4. 9
43 is
54 is
【answer】
F1 [i] [j] denotes the start of length i from j optimum combining scheme score
F2 [i] [j] denotes the start of length i from j worst score combining scheme
as a loop so the rock bit range extension , extends to n + 1..2 * n
enumeration length, starting enumeration, enumeration breakpoint.
DP wants to do then
[Code]
/*
f1[i][j]表示从i开始长度为j的最佳合并方案得分
f2[i][j]表示从i开始长度为j的最差合并方案得分
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100;
const int M = 1e4;
int n, s;
int f1[2*N + 10][N + 10], f2[2*N + 10][N + 10];
int a[2 * N + 10];
int main() {
//freopen("C://Users//Administrator//Desktop//测试数据//ch3//prog33//test//merge8.in","r",stdin);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) a[i + n] = a[i];
for (int i = 1; i <= 2 * n; i++) a[i] = a[i] + a[i - 1];
for (int i = 1; i <= 2 * n; i++) {
f1[i][1] = f2[i][1] = 0;
}
for (int l = 2; l <= n; l++) {
for (int i = 1; i <= 2 * n; i++) {
int j = i + l - 1;
if (j > 2 * n) break;
f1[i][l] = f1[i][1] + f1[i + 1][l - 1] + a[j] - a[i - 1];
f2[i][l] = f2[i][1] + f2[i + 1][l - 1] + a[j] - a[i - 1];
for (int k = 2; k <= l - 1; k++) {
f1[i][l] = max(f1[i][l], f1[i][k] + f1[i + k][l - k] + a[j] - a[i - 1]);
f2[i][l] = min(f2[i][l], f2[i][k] + f2[i + k][l - k] + a[j] - a[i - 1]);
}
}
}
int ma = f1[1][n], mi = f2[1][n];
for (int i = 2; i <= n; i++)
{
ma = max(ma, f1[i][n]);
mi = min(mi, f2[i][n]);
}
cout << mi << endl;
cout << ma << endl;
return 0;
}