算裸的树形dp吧 回来复习一波
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include#include #include #include 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;}