算裸的树形dp吧 回来复习一波
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int M=1007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int tot,cnt=1,k; int f[M][1005]; struct node{int w,v,l,r;}tr[M]; void dfs(int x){ tr[x].v=read(); k=read(); cnt++; if(!k){ tr[x].l=cnt; dfs(tr[x].l); tr[x].r=cnt; dfs(tr[x].r); }else tr[x].w=k; } void trdp(int x){ if(!tr[x].l&&!tr[x].r){ for(int i=2*tr[x].v;i<=tot;i++){ int now=(i-2*tr[x].v)/5; if(now<=tr[x].w) f[x][i]=now; else f[x][i]=tr[x].w; } return ; } if(tr[x].l) trdp(tr[x].l); if(tr[x].r) trdp(tr[x].r); for(int i=2*tr[x].v;i<=tot;i++){ int l=tr[x].l,r=tr[x].r; for(int j=0;j<=i-(2*tr[x].v);j++) f[x][i]=max(f[x][i],f[l][j]+f[r][i-(2*tr[x].v)-j]); } } int main() { tot=read(); dfs(1); trdp(1); printf("%d\n",f[1][tot]); return 0; }