Description
Input
Output
Sample Input
7 9 39 6 13 2 22 6 7 4 -19 5 28 6 -17 1 2 1 3 2 4 1 5 4 6 2 7 3
Sample Output
52
Data Constraint
做法:一道非常经典的依赖背包问题,将树的dfs序求出后,设f[i][j]表示处理完i到n的数后毒素为j的最大价值。
状态转移如下:f[i][j]=max(f[i][j],f[i+1][j-p[i]]+v[i]) {选取当前果实}
f[i][j]=max(f[i][j],f[i+size[x]]){不选}
size[x]表示dfs序中第i位的点的子树大小。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 2007 5 #define M 10007 6 using namespace std; 7 int f[N][M],ls[N],tot,v[N],p[N],n,m,size[N],d[N],cnt; 8 struct edge{ 9 int to,next; 10 }e[N*2]; 11 12 void Add(int x,int y){ 13 e[++tot].to=y; 14 e[tot].next=ls[x]; 15 ls[x]=tot; 16 } 17 18 void Dfs(int x,int fa){ 19 d[++cnt]=x; 20 for (int i=ls[x];i;i=e[i].next){ 21 if (e[i].to==fa) continue; 22 Dfs(e[i].to,x); 23 size[x]+=size[e[i].to]; 24 } 25 size[x]++; 26 } 27 28 int main(){ 29 scanf("%d%d",&n,&m); 30 for (int i=1;i<=n;i++) scanf("%d%d",&v[i],&p[i]); 31 for (int i=1;i<=n-1;i++){ 32 int x,y; 33 scanf("%d%d",&x,&y); 34 Add(x,y); 35 Add(y,x); 36 } 37 Dfs(1,0); 38 for (int i=n;i>=1;i--) 39 for (int j=m;j>=0;j--){ 40 if (j-p[d[i]]>=0) f[i][j]=max(f[i][j],f[i+1][j-p[d[i]]]+v[d[i]]); 41 f[i][j]=max(f[i][j],f[i+size[d[i]]][j]); 42 } 43 int ans=0; 44 for (int i=0;i<=m;i++) 45 ans=max(ans,f[1][i]); 46 printf("%d",ans); 47 }