zoj3626 Treasure Hunt I 树上DP

来源:互联网 发布:傲世奇侠传java 编辑:程序博客网 时间:2024/06/06 02:43

点击打开链接

题意:

给你一颗树,然后每个点有一个价值,每个边有一个代价,然后问你,从k点出发,花费最多m/2的代价,能够取得最多的价值是多少。

思路:

树上背包问题,dp[i][j]表示从i点出发,花费j的代价所能取得的最大价值是多少。
转移方程为 dp[i][j]=max(dp[i][j],dp[i][m-k-t[i][v]]+dp[v][k])  就是以u为父节点 走不走v这个点   从不同的费用转移过来


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;typedef long long ll;const int maxn = 5e4+10;int n,val[105],k,m;int dp[105][205],vis[105];vector<pair<int,int> > G[105];void dfs(int u){vis[u] = 1;dp[u][0] = val[u];for(int i=0; i<G[u].size(); i++){int v = G[u][i].first, w = G[u][i].second;if(vis[v]==0){dfs(v);for(int j=m; j>=0; j--)for(int k=0; k<=j-w; k++)dp[u][j] = max(dp[u][j],dp[u][j-k-w]+dp[v][k]);}}}int main(){while(cin >> n){memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++)        G[i].clear();for(int i=1; i<=n; i++){cin >> val[i];dp[i][0] = val[i];}for(int i=1; i<=n-1; i++){int a,b,c; cin>>a>>b>>c;G[a].push_back(make_pair(b,c));G[b].push_back(make_pair(a,c));}cin >> k >> m;m = m/2;dfs(k);int ans = 0;for(int i=0; i<=m; i++)if(dp[k][i] > ans)ans = max(ans,dp[k][i]);cout << ans << endl;}}


0 0
原创粉丝点击