#include<bits/stdc++.h>usingnamespace std;constint N =35;int n;int w[N];int f[N][N], g[N][N];/*
f[i][j]记录i到j的最大加分书
g[i][j]记录i到j的根节点
*/voiddfs(int l,int r){if(l > r)return;int k = g[l][r];
cout<<k<<" ";dfs(l, k -1);dfs(k +1, r);}intmain(){
cin>>n;for(int i =1; i <= n; i ++) cin>>w[i];for(int len =1; len <= n; len ++){//枚举区间跨度 for(int l =1; l + len -1<= n; l ++){//枚举左端点 int r = l + len -1;//确定右端点 if(len ==1){//如果区间长度为1
f[l][r]= w[l];// 初始化单个节点的加分数
g[l][r]= l;//初始化单个节点为自己的根节点 }else{for(int k = l; k <= r; k ++){//遍历决策点 int left = k == l ?1: f[l][k -1];//左子树如果是区间左端就让他为加数1,否则为左子树的最大加数和 int right = k == r ?1: f[k +1][r];//右子树如果是区间右端就让他为加数1,否则为右子树的最大加数和int score = right * left + w[k];//计算这个节点的加数和 if(score > f[l][r]){//如果大于原先的,就进行重新赋值
f[l][r]= score;//更新最大值
g[l][r]= k;//因为区间[l,r]的最大值是在k为决策点找到的,所以k为这颗子树的根节点 }}}}}
cout<<f[1][n]<<endl;dfs(1, n);return0;}
原题传送门#include<bits/stdc++.h>using namespace std;const int N = 35;int n;int w[N];int f[N][N], g[N][N];/*f[i][j]记录i到j的最大加分书g[i][j]记录i到j的根节点 */ void dfs(int l, int r){ if(l > r) return ; int k = g[l][r]; cout<<k<<" "; d