HDU 1561 - The more, The Better


HDU 1561 - The more, The Better
Problem Description
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
Input
每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
Output
对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量 

Sample Input
3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7 6 2 2 0 0

Sample Output
5 13
http://blog.csdn.net/woshi250hua/article/details/7637847
解题思路:和Poj1155、1947一样,都是在树形结构上进行分组背包处理。本题的依赖关系可以理解成树边,到达子节点必须先经过父节点,本质是一样的,这样可以建立起一个森林,如果为每棵树的添加一个公共父节点0那就成了一棵树了,这是个实用性很强的小技巧。建立起一棵树就开始如何进行dp,如何从子节点获取信息。
    一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m)时选最多的宝物,而一个子节点中只可以选择一个状态进行转移,每个节点有若干个子节点,问题就转换为分组背包,几个子节点就是几个分组背包,体积是选几个地点,价值是宝物价值。
     状态转移方程: dp[v][1] = Money[v]; (v为叶子节点)
                          dp[v][j] = max(dp[v][j],dp[v][j-i] + dp[k][i] );(v为非叶子节点,j表示用户个数,i为容量,k为v的子节点,)
    算法复杂度O(sum(num[i],num[s])) (num[i]为某个节点的叶子子孙个数,num[s]为i的子节点的叶子子孙个数)
    本题加了个剪枝,每次转移时不必都从最大容量m开始,而可以把当前可能转移的最大容量算出来进行转移,最大容量就是子节点个数,速度快了10几倍。
以树来存储各城堡之间的依赖关系。
首先说状态表示,dp[i][j]表示在以i为根节点的子树上攻破j个城堡可达到的最大收益。
为方便表示,以0号节点为总的根节点。
http://blog.csdn.net/harrypoirot/article/details/25426315
  1. vector<int>   map[205];  
  2. int val[205],dp[205][205];  
  3. int n,m;  
  4. //dp[i][j]:以第i个节点为起始,攻击j次的最大获益  
  5.   
  6. inline int bet(int x,int y)  
  7. {  
  8.     if(x>y)  return x;  
  9.     return y;  
  10. }  
  11. void dfs(int bg,int c)  
  12. {  
  13.     int size=map[bg].size();  
  14.     dp[bg][1]=val[bg];//只攻击该节点  
  15.       
  16.     for(int i=0;i<size;++i)//对于bg的所有子节点做01背包  
  17.     {  
  18.         if(c>1)  dfs(map[bg][i],c-1);  
  19.         //若未到最后,则继续向下深搜,先算好将来所需的数据  
  20.   
  21.         for(int j=c;j>1;--j)//当背包容量为c时,j=1时为只选bg  
  22.         {  
  23.             for(int k=0;k<=j-1;++k)  
  24.             {  
  25.                 //攻击了第i个子节点下的k个节点,那么还剩下j-k次机会攻击其余的  
  26.                 dp[bg][j]=bet(dp[bg][j],dp[bg][j-k]+dp[map[bg][i]][k]);  
  27.             }  
  28.         }  
  29.     }  
  30. }  
  31.   
  32. int main()  
  33. {  
  34.     while(cin>>n>>m)  
  35.     {  
  36.         if(n==0&&m==0)  break;  
  37.   
  38.         memset(val,0,sizeof(val));  
  39.         memset(dp,0,sizeof(dp));  
  40.         for(int i=0;i<=n;++i)    map[i].clear();  
  41.         int a,b;  
  42.         for(int i=1;i<=n;++i)  
  43.         {  
  44.             scanf("%d%d",&a,&b);  
  45.             map[a].push_back(i);  
  46.             val[i]=b;  
  47.         }  
  48.   
  49.         dfs(0,m+1);//从‘0’开始  
  50.         cout<<dp[0][m+1]<<endl;  
  51.     }  
  52. }  

http://blog.csdn.net/me4546/article/details/6612253
  1. /* 
  2.  
  3. dp[i][j]代表以i为根节点,一共选取j个节点所取得的最大价值,i这个节点一定要选 
  4. dp_temp[i][j]代表以i为根节点,一共选取j个节点所取得的最大价值,i这个节点一定不选 
  5.  
  6. 那么   dp[i][j+1]=dp_temp[i][j]+val[i]; 
  7.          dp_temp[i][j+k]=max(dp_temp[i][j+k],dp_temp[i][j]+dp[son[i]][k]); 
  8.          
  9. 解释一下 dp_temp[i][j]+dp[son[i]][k],其中 son[i]代表i这个节点的孩子节点, 
  10.          假设son[i]这个节点中存在选取K个节点这个状态,那么这个孩子节点就 
  11.          可以向dp_temp[i][j+k]转移,因为转移的时候都是从孩子转移过来的, 
  12.          那么要是选择了son[i]这个节点,这个节点本身是一定要选择的, 
  13.          所以转移方程不是 + dp_temp[son[i]][k],而是 +dp[son[i]][k]  
  14.           
  15. */
  16. vector<int> E[N];  
  17. int dp_temp[N][N],dp[N][N];  
  18. int val[N],n,m;  
  19. bool h[N];  
  20.   
  21. void init(int n){  
  22.     val[0]=0;  
  23.     for(int i=0;i<=n;i++)  
  24.         E[i].clear();  
  25.     memset(h,0,sizeof(h));  
  26.     memset(dp,-1,sizeof(dp));  
  27.     memset(dp_temp,-1,sizeof(dp_temp));  
  28. }  
  29.   
  30. void dfs(int u){  
  31.     if(h[u]) return;  
  32.     h[u]=1;  
  33.     dp_temp[u][0]=0;  
  34.     for(int i=0;i<E[u].size();i++){  
  35.         int v=E[u][i];  
  36.         if(!h[v])  
  37.             dfs(v); //叶子节点未访问过则继续访问   
  38.         for(int j=m;j>=0;j--)  
  39.             for(int k=1;k+j<=m;k++)  
  40.                 if(dp_temp[u][j]!=-1&&dp[v][k]!=-1){  
  41.                     if(dp_temp[u][j+k]<dp_temp[u][j]+dp[v][k])  
  42.                         dp_temp[u][j+k]=dp_temp[u][j]+dp[v][k];  
  43.                 }  
  44.     }  
  45.     for(int i=0;i<=m;i++)  
  46.         if(dp_temp[u][i]!=-1)  
  47.             dp[u][i+1]=dp_temp[u][i]+val[u];  
  48. }  
  49. int main(void){  
  50.     while(scanf("%d%d",&n,&m),n||m){  
  51.         init(n);  
  52.         for(int i=1;i<=n;i++){  
  53.             int u;  
  54.             scanf("%d%d",&u,&val[i]);  
  55.             E[u].push_back(i);  
  56.         }  
  57.         dfs(0);  
  58.         printf("%d\n",dp[0][m+1]);  
  59.     }  
  60. }  
还有一种直接一个数组

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts