生活随笔
收集整理的這篇文章主要介紹了
Tyvj1073
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接
分析:
我這個zz,老是不看題
總是因為做過一道題而跳過題目,所以忽視了很多條件
這道題,一開始我認(rèn)為是隨意n個點
求任一符合要求的前序遍歷
想了好久都覺得很困難
于是又讀了一遍題目
發(fā)現(xiàn)題目規(guī)定二叉樹的中序遍歷是1,2,3,4,…,n
如果標(biāo)算太難請堅定信念
不如回頭再看一眼題面 ——–Menci
一道區(qū)間dp
已知中序遍歷,那么一棵子樹的所有節(jié)點一定在序列中的一個連續(xù)區(qū)間內(nèi)
根節(jié)點一定在序列中
我們可以枚舉根節(jié)點
f[i][j]表示i~j的節(jié)點是一棵子樹
根節(jié)點是k
f[i][j]=max{f[i][k-1]*f[k+1][j]+a[k]}
至于最后的輸出,我們只要再用一個g數(shù)組記錄一下f[i][j]最優(yōu)情況下的根節(jié)點是哪個
最后遞歸輸出就好了
附樣例圖
tip
好好讀題
不要手殘
這里寫代碼片
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long longusing namespace std;
const int N=
35;
ll f[N][N];
ll a[N];
int g[N][N];
int n;
void print(
int l,
int r)
{
if (l>r)
return;
if (l==r){
printf(
"%d ",l);
return;}
printf(
"%d ",g[l][r]);print(l,g[l][r]-
1);print(g[l][r]+
1,r);
}
int main()
{
scanf(
"%d",&n);
for (
int i=
1;i<=n;i++)
scanf(
"%lld",&a[i]);
for (
int i=
1;i<=n;i++) f[i][i]=a[i];
int i,j,k;
for (i=n-
1;i>=
1;i--)
for (j=i+
1;j<=n;j++)
for (k=i;k<=j;k++){
if (k==i)
if (f[k+
1][j]+a[k]>f[i][j]){f[i][j]=f[k+
1][j]+a[k]; g[i][j]=k; }
if (k==j)
if (f[i][k-
1]+a[k]>f[i][j]){f[i][j]=f[i][k-
1]+a[k]; g[i][j]=k; }
if (k!=i&&k!=j)
if (f[i][k-
1]*f[k+
1][j]+a[k]>f[i][j]){f[i][j]=f[i][k-
1]*f[k+
1][j]+a[k];g[i][j]=k;} }
printf(
"%lld\n",f[
1][n]);print(
1,n);
return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/wutongtong3117/p/7673303.html
總結(jié)
以上是生活随笔為你收集整理的Tyvj1073的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。