题目链接:
题解思路:
这道题要用到动态规划中的背包
可以把 涂漆节点的个数 理解为背包容量 ,则每个节点的重量为1
dp[a][b] 表示包含a(根节点)的共b个节点的最大权值
然后通过后序遍历从下往上先求得子节点的最大权值,依次向上背包
最后得到的dp[1][v]则为答案
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define MAXN 105 using namespace std; vector<int>q[MAXN]; // int dp[MAXN][MAXN]; int n,v; int max(int a,int b) { return a>b?a:b; } void dfs_package(int loc) { for(int i=0;i<q[loc].size();i++) dfs_package(q[loc][i]); dp[loc][0]=0; for(int i=0;i<q[loc].size();i++) for(int j=v;j>=2;j--) //j只能到2 因为必须要保证dp[x][1]不被改变(包含根节点) for(int k=1;k<j;k++) //取第i棵子书的k个节点 dp[loc][j]=max(dp[loc][j],dp[loc][j-k]+dp[q[loc][i]][k]); } int main() { scanf("%d%d",&n,&v); for(int i=1;i<=n;i++) scanf("%d",&dp[i][1]); int a,b; for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); if(a<b) q[a].push_back(b); else q[b].push_back(a); } dfs_package(1); cout<<dp[1][v]<<endl; return 0; }
时间: 2024-10-12 23:22:46