找性质,倒推
我简直是傻逼,题都没看完,然后半天做不起
一道简单的树形DP,但是要卡空间
(f[i][u][v])从根到i,选了u条公路v条铁路的最小代价,显然答案是(f[1][0][0])
从叶子节点倒推
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=20004;
int n,lc[N],rc[N],f[88][44][44],top,st[88],a[N<<1],b[N<<1],c[N<<1];
inline void dfs(int x){
st[++top]=x;
memset(f[top],0x3f,sizeof(f[top]));
if(x>=n){
for(int u=0;u<=40;u++)
for(int v=0;v+u<=40;v++)
f[top][u][v]=c[x]*(a[x]+u)*(b[x]+v);
return;
}
dfs(lc[x]);dfs(rc[x]);
for(int u=0;u<=40;u++)
for(int v=0;v+u<=40;v++)
f[top-2][u][v]=min(f[top-2][u][v],min(f[top-1][u+1][v]+f[top][u][v],f[top-1][u][v]+f[top][u][v+1]));
if(rc[x])top--;
if(lc[x])top--;
}
signed main(){
n=read();
for(int i=1;i<n;i++){
lc[i]=read();rc[i]=read();
if(lc[i]<0)lc[i]=n-1-lc[i];
if(rc[i]<0)rc[i]=n-1-rc[i];
}
for(int i=n;i<(n<<1);i++){
a[i]=read();b[i]=read();c[i]=read();
}
dfs(1);
cout<<f[1][0][0];
return (0-0);
}