【每日一题】5月13日加分二叉树

加分二叉树

https://ac.nowcoder.com/acm/problem/16681

解题思路

区间dp
又又又是区间dp;看来是个极其重要的动态规划模型吖!
这里给出的数据规模小于等于30,很明显可以开下很多维的数组,运行的时间复杂度也很高。
题目第二行给出的是每个节点的初始值。我们要找到一个前序序列,让题目给出的函数值最大。
根据题目给出中序序列为 1 2 3 4 5 6 7 …… n那么树的样子一定是固定了的,与平衡树类似左子树的全部节点一定小于根节点,右子树大于。
那么在知道这个前提下就很好去进行递推了。首选区间dp。
从这里看出允许使用不带优化的区间dp,直接图片说明 怼上去就行了
我们二维数组 dp[i][j]表示从 i 到 j 满足题目中序遍历为(i i+1 …… j)的最大值。
那么状态转移就是根节点值加上左子树最大乘右子树最大,在区间(i,j)中枚举全部的决策点k,计算到最大即可。
注意特判没有左右子树的情况,别多加了个1。

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();    return s * w; }

const int N = 35;
ll dp[N][N], rt[N][N];
int a[N];

void dfs(int l, int r) {
    if (l > r)    return;
    int k = rt[l][r];
    printf("%d ", k);
    dfs(l, k - 1); //左子树
    dfs(k + 1, r); //右子树
}

int main() {
    int n = read();
    for (int i = 1; i <= n; ++i)    a[i] = read();
    for (int len = 1; len <= n; ++len) { //区间长度
        for (int l = 1; l + len - 1 <= n; ++l) { //起点
            int r = l + len - 1; //终点
            for (int k = l; k <= r; ++k) { //决策点
                ll lson = k == l ? 1 : dp[l][k - 1];
                ll rson = k == r ? 1 : dp[k + 1][r];
                ll tmp = lson * rson + a[k];
                if (l == r)    tmp = a[k]; //特判没有子树的情况,不然会多加1
                if (tmp > dp[l][r]) {
                    dp[l][r] = tmp;
                    rt[l][r] = k;
                }
            }
        }
    }
    printf("%lld\n", dp[1][n]);
    dfs(1, n);
    return 0;
}
每日一题 文章被收录于专栏

每日一题

全部评论

相关推荐

秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
10-11 17:30
湖南大学 C++
我已成为0offer的糕手:羡慕
点赞 评论 收藏
分享
有工作后先养猫:太好了,是超时空战警,我们有救了😋
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务