ural1018

来源:互联网 发布:java io面试题 编辑:程序博客网 时间:2024/06/03 12:40
题目大意:

有一棵二叉苹果树,共有N个结点,编号为1~N,树根编号一定是1用两个结点的编号来描述每一根树枝。现在这颗树枝条太多了,需要剪枝。但树枝上长有苹果。请问给定需要保留的树枝数量Q,求出最多能留住多少苹果。

输入格式:第12个数,NQ(1<=Q<= N,1<N<=100)N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。每根树枝上的苹果不超过30000个。

输出格式:一个数,最多能留住的苹果的数量。

开始学习树形DP,先水了一道题。

这个DP很好想,f[i][j]表示以i为根选j个苹果的max

f[i][j]=max(f[i][j],f[i的左儿子][k]+f[i的右儿子][j-k-1]+f[i][1])

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=300;struct node{int x,y,z,next,other;}sa[N];int len=0,first[N];int n,k;void ins(int x,int y,int z){len++;sa[len].x=x;sa[len].y=y;sa[len].z=z;sa[len].next=first[x];first[x]=len;}struct trnode{int l,r;trnode(){l=r=0;}}tr[N];bool tf[N];int f[N][N];void dfs(int x){for(int i=first[x];i!=-1;i=sa[i].next){int y=sa[i].y;if(tf[y]==true){tf[y]=false;f[y][1]=sa[i].z;if(tr[x].l==0) tr[x].l=y;else           tr[x].r=y;dfs(y);}}}int tr_dp(int x,int m){if(f[x][m]!=-1) return f[x][m];int maxx=0;for(int i=0;i<=m-1;i++){int ls=i,rs=(m-1)-i;int lans=tr_dp(tr[x].l,ls);int rans=tr_dp(tr[x].r,rs);   maxx=max(maxx,lans+rans+f[x][1]);}f[x][m]=maxx;return f[x][m];}int main(){scanf("%d%d",&n,&k);memset(first,-1,sizeof(first));for(int i=1;i<n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);ins(x,y,z);ins(y,x,z);}memset(tf,true,sizeof(tf));memset(f,-1,sizeof(f));tf[1]=false;dfs(1);for(int i=1;i<=n;i++) f[i][0]=0;f[1][1]=0;printf("%d\n",tr_dp(1,k+1));}


原创粉丝点击