hdu 3593
来源:互联网 发布:福建广电网络人工电话 编辑:程序博客网 时间:2024/04/19 00:57
终于理解树形依赖背包啦~
这个树形DP的转移方程还是比较简单的。
树形依赖背包的优化:
设当前结点为
所以直接令
最后强制加入物品
这样就在强制选取物品
与原问题相比,优化了泛化物品的合并,时间复杂度降到
时间复杂度:
另外这题数据有点小问题,读入部分要改成奇怪的方式才能过。。。QwQ
void init(){ for(int i = 1, father; i <= N; i++) {// read(cost[i]), read(att[i]), read(fa[i]); scanf("%d%d%d", &cost[i], &att[i], &father); if(father == i) father = 0; NewEdge(father, i); }}
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <vector>#include <utility>#include <stack>#include <queue>#include <iostream>#include <algorithm>template<class Num>void read(Num &x){ char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return;}template<class Num>void write(Num x){ if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]);}const int maxn = 1e5+50, maxG = 10005, rem = 505;int N, G, dp[rem][maxG];int cost[maxn], att[maxn], fa[maxn];struct Edge{ int v, next; Edge(int v = 0,int next = 0):v(v),next(next){}}edge[maxn];int head[maxn], el = 0;void NewEdge(int u,int v){ edge[++el] = Edge(v, head[u]), head[u] = el;}void dfs(int a,int size){ for(int i = head[a]; i; i = edge[i].next) { int p = edge[i].v; if(!head[p]) { for(int j = size; j >= cost[p]; j--) dp[a][j] = std::max(dp[a][j], dp[a][j - cost[p]] + att[p]); } else { if(size >= cost[p]) { for(int j = 0; j <= size - cost[p]; j++) dp[p][j] = dp[a][j]; dfs(p, size - cost[p]); for(int j = size; j >= cost[p]; j--) dp[a][j] = std::max(dp[a][j], dp[p][j - cost[p]] + att[p]); } } }}void clear(){ el = 0, cost[0] = att[0] = 0; memset(head, 0, sizeof(head)); memset(dp, 0, sizeof(dp)); }void init(){ for(int i = 1; i <= N; i++) { read(cost[i]), read(att[i]), read(fa[i]); if(fa[i] == i) fa[i] = 0; NewEdge(fa[i], i); }}int main(){#ifndef ONLINE_JUDGE freopen("3593.in","r",stdin); freopen("3593.out","w",stdout);#endif while(scanf("%d%d",&N,&G) != EOF) { clear(), init(); dfs(0, G); write(dp[0][G]), puts(""); }#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0;}
0 0
- hdu 3593
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- 第三周工作周报
- POJ 3641 Pseudoprime numbers
- LeetCode(20)Valid Parentheses
- GC垃圾收集算法
- Grep用法
- hdu 3593
- C++ class与内存
- LeetCode(141)(142) Linked List Cycle I II
- Linux - 有效群组(effective group)与初始群组(initial group),groups,newgrp
- 高仿SinaWeibo新浪微博发布页面话题效果
- 分享在MVC3.0中使用jQuery DataTable 插件
- FileOutputStream/FileInputStream--FileWriter/FileReader
- 相似图片搜索
- 提示磁盘被写保护怎么办?