P1040题解

题目链接

这是一道区间DP题,当然你说他是树形DP题也行.因为这道题给的是中序遍历,所以说分清左右子树是很容易的,这为我们使用DP创造了机会. 这里我们假设dp[i][j]表示给出的序列中i到j最大的值.由于是中序遍历,只要这一串是子树那么无论哪个元素是根结点都可以.

因此状态转移方程为

我们用区间DP简单实现即可.这里注意dp[i][i]的值就是a[i].

同时为了输出前序遍历我们记录一下每一段的根节点(root)

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=35;
int n,a[N],dp[N][N],root[N][N];
void work(int l, int r){
	if(l>r) return;
	cout<<root[l][r]<<' ';
	if(l==r) return;
	work(l,root[l][r]-1);
	work(root[l][r]+1,r);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) root[i][i]=i, dp[i][i-1]=1, dp[i][i]=a[i];
	for(int len=2;len<=n;len++){
		for(int i=1;i+len-1<=n;i++){
			int j=i+len-1;
			dp[i][j]=dp[i+1][j]+a[i], root[i][j]=i;
			for(int k=i+1;k<j;k++){
				if(dp[i][j]<dp[i][k-1]*dp[k+1][j]+a[k]){
					dp[i][j]=dp[i][k-1]*dp[k+1][j]+a[k];
					root[i][j]=k;
				}
			}
		}
	}cout<<dp[1][n]<<endl, work(1,n);
	return 0;
}
相关推荐
智驱力人工智能1 小时前
基于视觉分析的人脸联动使用手机检测系统 智能安全管理新突破 人脸与手机行为联动检测 多模态融合人脸与手机行为分析模型
算法·安全·目标检测·计算机视觉·智能手机·视觉检测·边缘计算
2301_764441331 小时前
水星热演化核幔耦合数值模拟
python·算法·数学建模
循环过三天1 小时前
3.4、Python-集合
开发语言·笔记·python·学习·算法
priority_key4 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
不染尘.4 小时前
2025_11_7_刷题
开发语言·c++·vscode·算法
似水এ᭄往昔4 小时前
【C++】--stack和queue
开发语言·c++
仰望—星空5 小时前
MiniEngine学习笔记 : CommandListManager
c++·windows·笔记·学习·cg·direct3d
来荔枝一大筐5 小时前
力扣 寻找两个正序数组的中位数
算法
算法与编程之美5 小时前
理解Java finalize函数
java·开发语言·jvm·算法
怕什么真理无穷6 小时前
C++面试4-线程同步
java·c++·面试