偷天换日(树形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;
}
posted @ 2019-08-01 21:46  凉如水  阅读(137)  评论(0编辑  收藏  举报