https://leetcode-cn.com/problems/minimum-cost-tree-from-leaf-values/
思路一:区间
d
p
dp
dp,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示合并
[
i
,
j
]
[i,j]
[i,j]所能得到的二叉树中非叶节点总和最小的值。枚举断点
k
k
k,表示我们先分别合并
[
i
,
k
]
[i,k]
[i,k]和
[
k
+
1
,
j
]
[k+1,j]
[k+1,j],再合并它们,那么有:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
]
[
j
]
,
d
p
[
i
]
[
k
]
+
d
p
[
k
+
1
]
[
j
]
+
M
a
x
[
i
]
[
k
]
∗
M
a
x
[
k
+
1
]
[
j
]
)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+Max[i][k]*Max[k+1][j])
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+Max[i][k]∗Max[k+1][j])。
class Solution {
public:
int mctFromLeafValues(vector<int>& arr) {
int siz=arr.size();
if(!siz)
return 0;
vector<vector<int>> MAX(siz,vector<int>(siz));
vector<vector<int>> dp(siz,vector<int>(siz,0x3f3f3f3f));
for(int i=0;i<siz;i++)
{
dp[i][i]=0;
MAX[i][i]=arr[i];
for(int j=i+1;j<siz;j++)
MAX[i][j]=max(MAX[i][j-1],arr[j]);
}
for(int len=1;len<siz;len++){
for(int i=0;i+len<siz;i++){
int j=i+len;
for(int k=i;k<j;k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+MAX[i][k]*MAX[k+1][j]);
}
}
return dp[0][siz-1];
}
};
思路二:单调栈。这个有点难想,看了别人的题解才学到。
class Solution {
public:
int mctFromLeafValues(vector<int>& arr) {
stack<int> s;
int siz=arr.size(),ans=0;
for(int i=0;i<siz;i++){
while(!s.empty()&&arr[i]>=s.top()){
int tmp=s.top();
s.pop();
if(s.empty())
ans+=tmp*arr[i];
else
ans+=tmp*min(arr[i],s.top());
}
s.push(arr[i]);
}
while(s.size()>=2){
int tmp=s.top();
s.pop();
ans+=tmp*s.top();
}
return ans;
}
};