题意:
一棵结点带权树,大小(结点数)为k的子树的权值和最大为多少。
题解:
树形DP模板+01背包模板
代码:
#include <set> #include <map> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> #define clr(str,x) memset(str,x,sizeof(str)) #define FRER() freopen("in.txt","r",stdin); #define FREW() freopen("out.txt","w",stdout); #define MAX_INF 0x7fffffff #define INF 0x3f3f3f3f #define maxn 110 using namespace std; typedef long long ll; int dp[maxn][maxn]; int w[maxn]; vector<int> G[maxn]; int n,k; void dfs(int root,int fa) { dp[root][1]=w[root]; for(int i=0; i<G[root].size(); i++) { int x=G[root][i]; if(x==fa) continue; dfs(x,root); // 0-1 背包 for(int j=k; j>0; j--) for(int r=0; r<j; r++) dp[root][j]=max(dp[root][j],dp[root][j-r]+dp[x][r]); } } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&k)!=EOF) { clr(G,0),clr(dp,0),clr(w,0); for(int i=0; i<n; i++) scanf("%d",&w[i]); for(int i=0; i<n-1; i++) { int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } dfs(0,-1); int Max=0; for(int i=0; i<n; i++) { Max=max(Max,dp[i][k]); } printf("%d\n",Max); } return 0; }