偷天换日(树形DP)
比较喜欢(≧∇≦)ノ这个建图
对于叶子节点,直接处理出f[i][j]当前i号节点分j个时间
#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
#define dec(i,l,r) for(int i=l;i>=r;--i)
const int maxm=90005,maxn=1005;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int T,k,tot,cnt,hd[maxn],f[maxn][maxn];
struct node{
int to,nt,w;
}e[maxn];
inline void add(int x,int y,int z)
{
e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].w=z;
}
inline void GET(int x)
{
int w,v;
rd(w);w<<=1;
add(x,++cnt,w);
w=cnt;
rd(v);
if(v){
int vi,wi;
inc(i,1,v)
{
rd(vi),rd(wi);
dec(j,T-1,0)
if(j<wi)break;
else f[w][j]=max(f[w][j],f[w][j-wi]+vi);
}
}
else
{
GET(w);
GET(w);
}
}
inline void DFS(int x)
{
for(int i=hd[x];i;i=e[i].nt)
{
int v=e[i].to;
DFS(v);
dec(j,T-1,0)
inc(k,1,j-e[i].w)
f[x][j]=max(f[x][j],f[x][j-k-e[i].w]+f[v][k]);
}
}
int main()
{
rd(T);
GET(0);
DFS(0);
int ans=0;
inc(i,0,T-1)
ans=max(ans,f[0][i]);
printf("%d",ans);
re 0;
}