zoj3626 Treasure Hunt I(树型dp+分组背包)
2016-02-19 14:48
274 查看
zoj3626
分析
题目意思就是首先告诉有n个地点,接着告诉你每个地点的财富值vi,再n-1行告诉你i j有一条路,花费t时间,然后告诉你从k点出发,在m天内回到k点,得到的最大价值。树上背包的入门题吧,对于m天回来,可以m/=2这样只要考虑出去不用考虑回来。状态表示很容易想到dp[i][j],i表示从i点出发,j表示天数时所获得的最大价值。进行一次dfs,进行分组背包。0~j-wa[u][v]相当于那个节点的分组物品。
题目
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3626代码
#include <cstdio> #include <algorithm> #include <vector> #include <cstring> #include <iostream> using namespace std; int val[110]; vector<int> ma[110]; int wa[110][110]; int dp[110][110]; int vis[110]; int n,k,m; void dfs(int u) { vis[u]=1; for(int i=0; i<ma[u].size(); i++) { int v=ma[u][i]; if(vis[v]==0) { dfs(v); for(int j=m; j>=0; j--) { for(int k=0; k<=j-wa[u][v]; k++) dp[u][j]=max(dp[u][j],dp[u][j-k-wa[u][v]]+dp[v][k]); } } } } int main() { while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); for(int i=1; i<=n; i++) ma[i].clear(); for(int i=1; i<=n; i++) { scanf("%d",&val[i]); dp[i][0]=val[i]; } for(int i=0; i<n-1; i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); ma[a].push_back(b); ma[b].push_back(a); wa[a][b]=wa[b][a]=c; } scanf("%d %d",&k,&m); m/=2; memset(vis,0,sizeof(vis)); dfs(k); int ans=-1; for(int i=0; i<=m; i++) { if(dp[k][i]>ans) ans=dp[k][i]; } printf("%d\n",ans); } }
相关文章推荐
- 分区
- Android 之Scrview与ListView ,GridView冲突的两种解决方案
- Tomcat关闭日志catalina.out
- Android 字符串拼接总结 String,StringBuffer与StringBuilder的区别??
- IOS 证书到期后如何处理
- 宏正自动科技发表新款8/16端口双滑轨LCD KVM多电脑切换器
- spark RDD 算子运行过程及分类
- 代理设置(wget/yum)
- ABI Management
- iTunes访问自己应用的沙盒
- 度量快速开发平台:网格部件批量更新数据
- Expires和Cache-Control的理解
- Kth Largest Element in an Array
- Html5页面中存放可拨打电话
- iOS开发之理解iOS中的MVC设计模式
- XCode设置(怎么让代码收缩)
- javascript Array.map 源码解读
- 虚拟机与开发板共享目录,nfs挂载文件系统
- Redis与Reactor模式
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治