題解:這個題可以用動態規劃或者記憶化搜尋來做。因為如果要求加分最大的話,必須要求它的兒子結點加分最大,所以就有了最優子階段。我們可以列舉根來更新最大值。中序遍歷有個特點,在中序遍歷這個序列上,某個點左邊的序列一定是這個點的左子樹,右邊的序列,一定在這個點的右子樹。root[i,j]表示[i,j]這段序列的根,遞迴輸出先序遍歷。注意初始化,f[i][i]=v[i],當序列只有i乙個元素時,f[i][i]等於這個點本身的權值,當l==r-1時,此時是空樹設為1。
c++版本一
#include #includeview code#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#define debug
#define ri register int
using
namespace
std;
typedef
long
long
ll;typedef __int128 lll;
const
int n=50
;const
int mod=1e9+7
;const
double pi = acos(-1.0
);const
double exp = 1e-8
;const
int inf = 0x3f3f3f3f
;int
t,n,m,k,q;
inta[n];
intdp[n][n];
introot[n][n];
int ser(int l,int
r) }
return
dp[l][r];
}void print(int l,int
r) printf(
"%d
",root[l][r]);
print(l,root[l][r]-1
); print(root[l][r]+1
,r);
}int
main()
printf(
"%d\n
",ser(1
,n));
print(
1,n);
//cout << "hello world!" << endl;
return0;
}
c++版本二
#include#includeview codeusing
namespace
std;
int n,v[39],f[47][47],i,j,k,root[49][49
];void print(int l,int
r) printf(
"%d
",root[l][r]);
print(l,root[l][r]-1
); print(root[l][r]+1
,r);
}int
main()
for(i=n; i>=1; i--)
for(j=i+1; j<=n; j++)
for(k=i; k<=j; k++)
}printf(
"%d\n
",f[1
][n]);
print(
1,n);
return0;
}
加分二叉樹
描述 設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subt...
加分二叉樹
設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subtree...
加分二叉樹
設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subtree...