HDU 6201 transaction transaction transaction(树形dp)
来源:互联网 发布:mac开发工具 编辑:程序博客网 时间:2024/06/07 20:50
http://acm.hdu.edu.cn/showproblem.php?pid=6201
和那个HDU 2196 Computer(树形DP) 应该差不多的吧。。
题意:给你一颗树,边有权值,现在有本书,每个点都有这本书的价格,现在你可以选任意一点作为起点买这本书,跑去任意一点卖掉,过程中消耗路径的权值花费,问你任选起点和终点最大收益是多少
看了代码;这个dp【0】【u】表示最小的价格,然后初始是买,所以就可以打到只买一次。。不过理论上可能MLE。但是没有。。应该要每次都清空当前的S
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn = 200005;typedef long long ll;const int inf = 0x3f3f3f3f;int f[maxn];int pc[maxn];int p[maxn];int dp[2][maxn];struct edge { int to; int cost; edge(int to, int cost) :to(to), cost(cost) {}};struct node { int id; int md; bool operator <(const node& s) const { return md < s.md; }};vector<edge> G[maxn];vector<node> S[maxn];void init(int n) { for (int i = 1; i <= n; i++) { G[i].clear(); S[i].clear(); } memset(dp, 0, sizeof(dp));}void dfs(int u, int fa,int c) { p[u] = c; f[u] = fa; dp[0][u] = pc[u]; for (int i = 0; i < G[u].size(); i++) { edge e = G[u][i]; if (e.to == fa) continue; int v = e.to; dfs(v, u,e.cost); node now; now.id = v; now.md = dp[0][v]+e.cost; S[u].push_back(now); } if (S[u].empty()) return; sort(S[u].begin(), S[u].end()); dp[0][u] = min(dp[0][u],S[u][0].md);}void dfs2(int u, int fa) { dp[1][u] = pc[u]; if (fa != -1) { if (S[fa][0].id != u) { dp[1][u] = min(dp[1][u],min(dp[1][fa], dp[0][fa]) + p[u]); } else { if (S[fa].size() == 1) dp[1][u] = min(dp[1][u],dp[1][fa] + p[u]); else dp[1][u] = min(dp[1][u],min(S[fa][1].md, dp[1][fa])+p[u]); } } for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].to; if (v == fa) continue; dfs2(v, u); }}int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); init(n); for(int i=1;i<=n;i++){ scanf("%d",&pc[i]); } for (int i = 2; i <= n; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); edge e(y,z); G[x].push_back(e); e.to=x; G[y].push_back(e); } dfs(1, -1, 0); dfs2(1, -1); int ans=0; for (int i = 1; i <= n; i++) { int sum=min(dp[0][i],dp[1][i]); ans=max(ans,pc[i]-sum); } printf("%d\n",ans); } return 0;}
还看到别人的这种做法,代码又短。又好。看来状态的定义很关键。。
参考http://blog.csdn.net/cillyb/article/details/77924055
dp[u][0]表示以u为根的子树中买一本书的最大收益,dp[u][1]表示以u为根的子树中卖一本书的最大收益。dp[u][0]+dp[u][1]即为在以u为根的子树中选两点的最大收益
心得:自己真的很少见到这样的方式。。。而且这个初始化。。。%
这样子把买和卖分开了,而且不用到父亲和儿子。。。。方式挺好的。
void dfs(int u, int pre) { dp[u][0] = -a[u]; dp[u][1] = a[u]; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i].v; int w = g[u][i].w; if(v == pre) continue; dfs(v, u); dp[u][0] = max(dp[u][0], dp[v][0]-w); dp[u][1] = max(dp[u][1], dp[v][1]-w); } ans = max(ans, dp[u][0]+dp[u][1]); }
阅读全文
0 0
- HDU-6201 transaction transaction transaction(树形dp)
- hdu 6201 transaction transaction transaction 树形dp
- HDU 6201 transaction transaction transaction(树形dp)
- HDU 6201 transaction transaction transaction (树形dp)
- HDU 6201 transaction transaction transaction【树形DP||SPFA最长路】
- HDU 6201transaction 【树形DP】
- 2017沈阳网络赛 1008 HDU 6201 transaction transaction transaction(树形dp)
- HDU 6201 transaction transaction transaction (树形DP or 拆点最短路)
- Hdu 6201 transaction transaction transaction 树型DP
- HDU 6201 transaction transaction transaction(dp)
- hdu 6201 transaction transaction transaction tree dp
- HDU 6201 transaction transaction transaction dp
- hdu 6201transaction transaction transaction
- HDU 6201 transaction transaction transaction
- hdu 6201 transaction transaction transaction
- HDU 6201 transaction transaction transaction
- hdu-6201 transaction transaction transaction
- hdu 6201 transaction transaction transaction
- 数据分析与软件
- WordBreakII_140
- 深入理解ES6箭头函数的this
- Leetcode315——Count of Smaller Numbers After Self
- mysql数据类型和常用字段
- HDU 6201 transaction transaction transaction(树形dp)
- 关于APP在小米5s第一次安装启动后,点击home返回桌面,再次进入重进闪屏页问题
- 浅析对象关系映射
- JSTL中foreach的使用与总结
- rails 常用命令
- Gradle学习系列之八——构建多个Project
- C#——快速排序
- JSP动态交互、JSP执行过程、JSP页面元素、JSP九大内置对象
- 程序员新手入门须知