JZOJ 5344. 摘果子

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 }
View Code

猜你喜欢

转载自www.cnblogs.com/traveller-ly/p/9610762.html