ZOJ 3626 Treasure Hunt I
2012-09-12 11:26
281 查看
一道树形DP+01背包的题。用dp[k][j]表示以k的根的树用j天最多可以得到多少宝藏,
m是天数限制,因为要往返,所以将m/2以后就可以直接计算单程的值了。
m是天数限制,因为要往返,所以将m/2以后就可以直接计算单程的值了。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> ///dp[k][j]表示以k的根的树用j天最多可以得到多少宝藏 using namespace std; const int MAXN = 105; int e; int n, k, m; int first[MAXN], next[MAXN << 1], v[MAXN << 1]; bool vis[MAXN]; int t[MAXN][MAXN], val[MAXN], dp[MAXN][MAXN]; void addedge(int x, int y) { v[e] = y, next[e] = first[x]; first[x] = e ++; } void ReadGraph() { for(int i = 1; i <= n; i ++) scanf("%d", &val[i]); e = 0; memset(vis, false, sizeof vis); memset(first, -1, sizeof first); for(int j = 0; j < n - 1; j ++) { int ui, vi, di; scanf("%d%d%d", &ui, &vi, &di); t[ui][vi] = t[vi][ui] = di; addedge(ui, vi); addedge(vi, ui); } scanf("%d%d", &k, &m); m /= 2; } void dfs(int k) { int i, j, x, s; vis[k] = true; for(s = first[k]; s != -1; s = next[s]) { x = v[s]; if(!vis[x]) { dfs(x); for(j = m; j >= t[k][x]; j --) //从k有足够的时间去x点 for(i = 0; i <= j - t[k][x]; i ++) { dp[k][j] = max(dp[k][j], dp[k][j - t[k][x] - i] + dp[x][i]); } } } } int main() { while(scanf("%d", &n) == 1) { ReadGraph(); for(int i = 1; i <= n; i ++) for(int j = 0; j <= m; j ++) dp[i][j] = val[i]; dfs(k); printf("%d\n", dp[k][m]); } return 0; }
相关文章推荐
- zoj 3626 Treasure Hunt I
- [zoj 3626]Treasure Hunt I 树DP
- zoj 3626 Treasure Hunt I(树背包)
- zoj 3626 Treasure Hunt I(树形背包)
- zoj - 3626 Treasure Hunt I
- ZOJ 3626 Treasure Hunt I(树形DP)
- zoj 3626 Treasure Hunt I (树形dp)
- zoj-3626 Treasure Hunt I (树形dp)
- ZOJ 3626 Treasure Hunt I 树上DP
- ZOJ Problem Set - 3626 Treasure Hunt I
- ZOJ 3626 —— Treasure Hunt I(树形DP + 背包)
- ZOJ 3626 Treasure Hunt I
- ZOJ 3626 Treasure Hunt I
- ZOJ 3626 Treasure Hunt I 树形背包
- ZOJ 3626 Treasure Hunt I
- ZOJ 3626 Treasure Hunt I(树形dp)
- ZOJ 3626 Treasure Hunt I (树形dp)
- Treasure Hunt I - ZOJ 3626 树形dp
- ZOJ 3626 Treasure Hunt I(树形dp)
- ZOJ 3626 Treasure Hunt I