poj2486Apple Tree(树形dp)
src: http://poj.org/problem?id=2486
思路:就像多重背包一样,dfs过子树后,子树就有了各种大小的代价,然后动态规划根的大小即可;
ac代码:
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> #include<iomanip> #include<stack> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) const int inf=99999999; int n,k,dp[105][2][205],val[105],vis[105];//dp[i][0][k]表示从i开始出发走k步不回到i的最大值,1表示回到i vector<int>head[105]; void init(){memset(dp,0,sizeof(dp));FOR(i,1,n)head[i].clear();memset(vis,0,sizeof(vis));} void add_edge(int u,int v){head[u].push_back(v);head[v].push_back(u);} void dfs(int u) { FOR(i,0,k)dp[u][0][i]=dp[u][1][i]=val[u]; vis[u]=1; for(int i=0;i<head[u].size();i++){ int v=head[u][i]; if(vis[v]==1)continue; dfs(v); for(int j=k;j>=0;j--){ for(int t=0;t<=j;t++){ dp[u][1][j+2]=max(dp[u][1][j+2],dp[u][1][j-t]+dp[v][1][t]); dp[u][0][j+2]=max(dp[u][0][j+2],dp[u][0][j-t]+dp[v][1][t]); dp[u][0][j+1]=max(dp[u][0][j+1],dp[u][1][j-t]+dp[v][0][t]); } } } } int main() { std::ios::sync_with_stdio(false); while(cin>>n>>k){ init(); int a,b; FOR(i,1,n)cin>>val[i]; for(int i=1;i<n;i++){cin>>a>>b;add_edge(a,b);} dfs(1); cout<<max(dp[1][0][k],dp[1][1][k])<<endl; } return 0; }

浙公网安备 33010602011771号