P1040 [NOIP2003 提高组] 加分二叉树
P1040 [NOIP2003 提高组] 加分二叉树
题目描述
设一个
若某个子树为空,规定其加分为
试求一棵符合中序遍历为
-
的最高加分。 -
的前序遍历。
对于全部的测试点,保证
解法
因为中序遍历保证是
我们考虑区间
则有状态转移方程:
那么第一问就做完了。
我们可以在转移的时候加一个判断,用
用代码表示就是:
if(dp[i][j] < dp[i][k - 1] * dp[k + 1][j] + dp[k][k]){
dp[i][j] = dp[i][k - 1] * dp[k + 1][j] + dp[k][k];
rt[i][j] = k;
}
题目要求输出前序遍历,则递归输出即可。
code:
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int MAXN = 35;
int n;
int val[MAXN];
int dp[MAXN][MAXN];
int rt[MAXN][MAXN];
void print(int l,int r){
if(l > r) return;
cout << rt[l][r] << " ";
print(l,rt[l][r] - 1);
print(rt[l][r] + 1,r);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i = 0;i <= MAXN - 1;i++){
for(int j = 0;j <= MAXN - 1;j++){
dp[i][j] = 1;
}
}
for(int i = 1;i <= n;i++) cin >> val[i],dp[i][i] = val[i];
for(int i = 1;i <= n;i++) rt[i][i] = i;+
for(int len = 2;len <= n;len++){
for(int i = 1;i <= n - len + 1;i++){
int j = i + len - 1;
for(int k = i;k <= j;k++){
if(dp[i][j] < dp[i][k - 1] * dp[k + 1][j] + dp[k][k]){
dp[i][j] = dp[i][k - 1] * dp[k + 1][j] + dp[k][k];
rt[i][j] = k;
}
}
}
}
cout << dp[1][n] << endl;
print(1,n);
return 0;
}
本文来自博客园,作者:wyl123ly,转载请注明原文链接:https://www.cnblogs.com/wyl123ly/p/18496602
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2023-10-23 [CSP-S 2023] 密码锁