Stone merger (dynamic programming)

Title Description

Playground around a circular stones piled placed NN, Stone is to have order to merge into a pile. Each time only a predetermined selected adjacent stack 2 into a new pile and the new pile of stones number, remember that the combined score.

Test design an algorithm to calculate the combined NN stones piled into stack 11 and the maximum score is the minimum score.

Input Format

The data line 11 is a positive integer NN, N represents stones piled there.

Line 22 has NN integers, the first integer a_iai ii ii stack represents the number of stones.

Output Format

The output common line 22, 11 is the minimum score, the maximum score is 22 acts.

Sample input and output

Entry 

4
4 5 9 4

Export 

43
54
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

#define N 201
#define INF 1000000
#define DEF -1

int stone[N];
int Min[N][N], Max[N][N], sum[N];
int min_circle = 0;
int max_circle = 0;

void Get_Score(int n) {
    memset(Min, 0, sizeof(Min));
    memset(Max, 0, sizeof(Max));
    memset(sum, 0, sizeof(sum));
    for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + stone[i];
    for (int r = 1; r <= (n - 1); r++) {
        for (int i = 1; i <= (n - r); i++) {
            int j = i + r;
            Min[i][j] = INF;
            Max[i][j] = DEF;
            for (int k = i; k < j; k++) {
                Min[i][j] = min(Min[i][j], Min[i][k] + Min[k + 1][j] + sum[j] - sum[i - 1]);
                Max[i][j] = max(Max[i][j], Max[i][k] + Max[k + 1][j] + sum[j] - sum[i - 1]);
            }
        }
    }
}

void Circular(int n) {
    for (int i = n + 1; i < (2 * n); i++) stone[i] = stone[i - n];
    Get_Score(2 * n - 1);
    min_circle = Min[1][n];
    max_circle = Max[1][n];
    for (int i = 2; i <= n; i++) {
        min_circle = min(min_circle, Min[i][n + i - 1]);
        max_circle = max(max_circle, Max[i][n + i - 1]);
    }
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> stone[i];
    }
//    Get_Score(n);
    Circular(n);
//    cout << Min[1][n] << endl;
//    cout << Max[1][n] << endl;
    cout << min_circle << endl;
    cout << max_circle << endl;
    return 0;
}

 

Published 98 original articles · won praise 5 · views 10000 +

Guess you like

Origin blog.csdn.net/chengsilin666/article/details/104108242