记忆化搜索
dp[i]表示有i个节点的树的最小权值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2025;
ll dp[N];
//dp[i] 有i个节点的树的最小权值
ll dfs(int u){//u个节点的最小权值
if(dp[u]!=0x3f3f3f3f3f3f3f3f) return dp[u];
for(int i=0;i<u;i++){//左子树i个节点
int j=u-i-1;//右子树i个节点
dp[u]=min(dp[u],1+2*dfs(i)+3*dfs(j)+i*i*j);
}
return dp[u];
}
int main(){
memset(dp,0x3f,sizeof dp);
dp[0]=0;
cout<<dfs(2021);
}
动态规划
虽然得到这题的答案是一样的,但个人认为这个做法有问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2025;
ll dp[N];
//dp[i] 有i个节点的树的最小权值
int main(){
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(int i=0;i<=2021;i++)
for(int j=0;j<i;j++)
dp[i]=min(dp[i],1+2*dp[j]+3*dp[i-j-1]+j*j*(i-j-1));
cout<<dp[2021];
}