20分求助
查看原帖
20分求助
638723
hhhqqq楼主2023/4/9 11:19
#include <iostream>
#include <cstring>
#include <algorithm>
#include <limits.h>

using namespace std;
 
const int N = 35;

int n;
int a[N];
int dp[N][N]; // dp数组保存区间[i,j]内构成的最大加分

void dfs(int left, int right)
{
    if (left > right) return; // 边界条件
    if (left == right) { // 叶子节点的处理
        cout << left << " ";
        return;
    }
    int root = 0, ans = INT_MIN;
    for (int i = left; i <= right; i++) {
        int sum = dp[left][i - 1] * dp[i + 1][right] + a[i]; // 每个节点作为根时所得到的加分
        if (sum > ans) {
            ans = sum; // 更新最优加分
            root = i; // 记录当前的根节点
        }
    }
    cout << root << " "; // 输出前序遍历序列
    dfs(left, root - 1); // 构造左子树
    dfs(root + 1, right); // 构造右子树
}

int main()
{
    cin >> n;
    
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    //初始化dp数组
    for (int len = 1; len <= n; len++) { // 区间长度
        for (int i = 1; i + len - 1 <= n; i++) { // 左端点 
            int j = i + len - 1; // 右端点
            if (i == j) dp[i][j] = a[i];
            else {
                dp[i][j] = INT_MIN; // 初始化为极小值
                for (int k = i; k <= j; k++) {
                    dp[i][j] = max(dp[i][j], dp[i][k - 1] * dp[k + 1][j] + a[k]); // 计算区间最优加分
                }
            }
        }
    }

    cout << dp[1][n] << endl; // 输出最高加分 

    dfs(1, n); // 构造前序遍历序列

    return 0;
}

2023/4/9 11:19
加载中...