您的位置:首页 > 移动开发

POJ2486 Apple Tree 【树上背包】

2018-08-10 20:29 393 查看

一句话题意:一棵树,一共n个点,每个点上有一个权值,求从1出发,走k步,最多能遍历到的权值。可以往回走。

第一(二)道树上背包题,先是看了dalao的题解,改了一点就过样例了。然而....TLE??? 改了挺久发现由于多组数据且没有“0 0”的输入,如果不在读入的时候加“~”或“EOF”就会死循环,从而导致TLE。

状态设计:设f[i][j][0/1]为以i为根的子树上,走j步,能得到的最大权值(0/1的表示会在转移方程中描述) 考虑:(此处参考dalao@zubizakeli ,侵删qwq)每个节点在最终答案中的类型:1,不经过;2,经过但不返回;3,经过且返回 (返回的定义是最终的停止节点不位于该节点的子树中) 那么可以进行转移:

 

1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4
5 using namespace std;
6
7 int n,k,tot;
8 int w[300],head[300];
9 int f[300][200][3];
10 struct node{
11     int to,next,val;
12 }edge[300];
13
14 void add(int x,int y)
15 {
16     edge[++tot].to=y;
17     edge[tot].next=head[x];
18     head[x]=tot;
19 }
20
21 void read(int &x)
22 {
23     x=0;
24     char ch=getchar();
25     bool flag=false;
26     while(ch<'0'||ch>'9') flag|=(ch=='-'),ch=getchar();
27     while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
28     x=flag ? -x : x;
29 }
30
31 void TreeDp(int u,int fa)
32 {
33     for(int i=0;i<=k;i++) f[u][i][1]=w[u],f[u][i][0]=w[u];
34     for(int i=head[u];i;i=edge[i].next)
35     {
36         int v=edge[i].to;
37         if(v==fa) continue;
38         TreeDp(v,u);
39         for(int kk=k;kk>=0;kk--)
40         for(int j=0;j<=kk;j++)
41         {
42             if(kk>=j+2) f[u][kk][0]=max(f[u][kk][0],f[v][j][0]+f[u][kk-j-2][0]);
43             if(kk>=j+2) f[u][kk][1]=max(f[u][kk][1],f[v][j][0]+f[u][kk-j-2][1]);
44             if(kk>=j+1) f[u][kk][1]=max(f[u][kk][1],f[v][j][1]+f[u][kk-j-1][0]);
45         }
46     }
47 }
48
49 void init()
50 {
51     memset(f,0,sizeof(f));
52     memset(head,0,sizeof(head));
53     tot=0;
54 }
55
56 int main()
57 {
58     while(scanf("%d%d",&n,&k)!=EOF)
59     {
60         for(int i=1;i<=n;i++) read(w[i]);
61         for(int i=1;i<=n-1;i++)
62         {
63             int x=0,y=0;
64             read(x),read(y);
65             add(x,y),add(y,x);
66         }
67         TreeDp(1,-1);
68         printf("%d\n",max(f[1][k][0],f[1][k][1]));
69         init();
70     }
71     return 0;
72 }
View Code 小结:分类讨论常常也是解题重要的突破口呐。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: