HDU-3672-Caves
2017-10-12 17:55
78 查看
ACM模版
设 dp[i][j][k] 表示以 i 为子树根遍历 j 个结点,k=0 表示遍历结束回到该子树根,k=1 表示不回。
对于 k=0 的情况,当遍历子结点时,可以考虑原本的有返回遍历路径插入对应子结点的有返回遍历路径及衔接这两条路径的花费;
对于 k=1 的情况,当遍历子结点时,可以考虑原本的无返回遍历路径插入对应子结点的有返回遍历路径及衔接这两条路径的花费;也可以考虑为原本的有返回遍历路径接上对应子结点的无返回遍历路径及衔接这两条路径的花费。
上述思路核心就是 dp[i][j][k] 的定义,只要定义好,剩下的路径关系就比较容易推出来,也不会出现遗漏。
最后询问时访问一下 dp[root][k][0] 和 dp[root][k][1] 中至少有一个小于等于 x 即最大花费的 k,k 要求尽量大,所以从 k=n 开始从大到小遍历即可。
描述
题解
树型 DP。设 dp[i][j][k] 表示以 i 为子树根遍历 j 个结点,k=0 表示遍历结束回到该子树根,k=1 表示不回。
对于 k=0 的情况,当遍历子结点时,可以考虑原本的有返回遍历路径插入对应子结点的有返回遍历路径及衔接这两条路径的花费;
对于 k=1 的情况,当遍历子结点时,可以考虑原本的无返回遍历路径插入对应子结点的有返回遍历路径及衔接这两条路径的花费;也可以考虑为原本的有返回遍历路径接上对应子结点的无返回遍历路径及衔接这两条路径的花费。
上述思路核心就是 dp[i][j][k] 的定义,只要定义好,剩下的路径关系就比较容易推出来,也不会出现遗漏。
最后询问时访问一下 dp[root][k][0] 和 dp[root][k][1] 中至少有一个小于等于 x 即最大花费的 k,k 要求尽量大,所以从 k=n 开始从大到小遍历即可。
代码
#include <iostream> #include <cstdio> #include <cstring> #define clr(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int MAXN = 510; int n, q; int root; int hed[MAXN]; int nxt[MAXN]; int cost[MAXN]; bool vis[MAXN]; ll dp[MAXN][MAXN][2]; void dfs(int x) { dp[x][1][0] = dp[x][1][1] = 0; for (int i = hed[x]; i; i = nxt[i]) { dfs(i); for (int j = n; j >= 2; j--) { for (int k = 1; k < j; k++) { dp[x][j][0] = min(dp[x][j][0], dp[x][k][0] + dp[i][j - k][0] + cost[i] * 2); dp[x][j][1] = min(dp[x][j][1], min(dp[x][k][1] + dp[i][j - k][0] + cost[i] * 2, dp[x][k][0] + dp[i][j - k][1] + cost[i])); } } } } int main() { int ce = 1; while (cin >> n && n) { cout << "Case " << ce++ << ":" << endl; clr(dp, 0x3f); clr(hed, 0); clr(vis, 0); int a, b, c; for (int i = 1; i < n; i++) { scanf("%d%d%d", &a, &b, &c); a++; b++; vis[a] = true; nxt[a] = hed[b]; hed[b] = a; cost[a] = c; // a 与 父亲 连边的花费 } for (int i = 1; i <= n; i++) { if (!vis[i]) { root = i; dfs(i); break; } } cin >> q; int x, k; for (int i = 0; i < q; i++) { scanf("%d", &x); k = n; while (dp[root][k][0] > x && dp[root][k][1] > x) { k--; } printf("%d\n", k); } } return 0; }
相关文章推荐
- HDU - 3672 Caves【树形DP+背包】
- HDU 3672 Caves ACM/ICPC 2007 成都区域赛 C 背包+树形DP
- hdu 4016 Magic Bitwise And Operation
- HDU 4727 The Number Off of FFF (水)
- hdu 3400(三分)
- hdu 5768 Lucky7 容斥原理 中国剩余定理
- HDU 5040
- HDU 1158 Employment Planning
- HDU 6053 容斥dp 或 莫比乌斯反演
- hdu 6082 度度熊与邪恶大魔王(完全背包)
- HDU 4565 So Easy! 矩阵快速幂
- HDU 3791 二叉搜索树
- HDU Image Recognition
- hdu 1982 Kaitou Kid - The Phantom Thief (1) (水。。)
- hdu-水仙花数
- HDU 1061 Rightmost Digit
- hdu 4450 Draw Something
- HDU1978--How many ways
- hdu 2767 超内存 哪位大神能帮忙改改
- hdu2955 Robberies