HDU 1011 - Starship Troopers


http://acm.hdu.edu.cn/showproblem.php?pid=1011
Problem Description
You, the leader of Starship Troopers, are sent to destroy a base of the bugs. The base is built underground. It is actually a huge cavern, which consists of many rooms connected with tunnels. Each room is occupied by some bugs, and their brains hide in some of the rooms. Scientists have just developed a new weapon and want to experiment it on some brains. Your task is to destroy the whole base, and capture as many brains as possible.

To kill all the bugs is always easier than to capture their brains. A map is drawn for you, with all the rooms marked by the amount of bugs inside, and the possibility of containing a brain. The cavern's structure is like a tree in such a way that there is one unique path leading to each room from the entrance. To finish the battle as soon as possible, you do not want to wait for the troopers to clear a room before advancing to the next one, instead you have to leave some troopers at each room passed to fight all the bugs inside. The troopers never re-enter a room where they have visited before.

A starship trooper can fight against 20 bugs. Since you do not have enough troopers, you can only take some of the rooms and let the nerve gas do the rest of the job. At the mean time, you should maximize the possibility of capturing a brain. To simplify the problem, just maximize the sum of all the possibilities of containing brains for the taken rooms. Making such a plan is a difficult job. You need the help of a computer.
Input
The input contains several test cases. The first line of each test case contains two integers N (0 < N <= 100) and M (0 <= M <= 100), which are the number of rooms in the cavern and the number of starship troopers you have, respectively. The following N lines give the description of the rooms. Each line contains two non-negative integers -- the amount of bugs inside and the possibility of containing a brain, respectively. The next N - 1 lines give the description of tunnels. Each tunnel is described by two integers, which are the indices of the two rooms it connects. Rooms are numbered from 1 and room 1 is the entrance to the cavern.

The last test case is followed by two -1's.
Output
For each test case, print on a single line the maximum sum of all the possibilities of containing brains for the taken rooms.
Sample Input
5 10 50 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 1 1 20 7 -1 -1
Sample Output
50 7

http://www.acmerblog.com/hdu-1011-Starship-Troopers-1266.html
1011 题目大意:一棵树,有n个结点,每个结点有v个bug,有w的brain。我从1号结点开始走,带着m个战士。
1个战士可以消灭20个bugs,如果我把某个结点的所有bug都消灭了我就能得到那个结点的brain。
如果想攻击当前结点,那么必须先攻击了它的父结点(1号点除外)。
其中当你攻占了当前结点,你可以分派人手,走向几个不同的子结点,去攻占更多。也就是说,不是单一的路径。
http://blog.csdn.net/shuangde800/article/details/10069771

题意

有n个洞穴编号为1~n,洞穴间有通道,形成了一个n-1条边的树, 洞穴的入口即根节点是1。
每个洞穴有x只bugs,并有价值y的金子,全部消灭完一个洞穴的虫子,就可以获得这个洞穴的y个金子.
现在要派m个战士去找金子,从入口进入。每次只有消灭完当前洞穴的所有虫子,才可以选择进入下一个洞穴。
一个战士可以消灭20只虫子,如果要杀死x只虫子,那么要x/20向上取整即(x+19)/20个战士。
如果要获得某个洞穴的金子,必须留下足够杀死所有虫子的战士数量, 即(x+19)/20个战士,然后这些留下战士就不能再去其它洞穴
其他战士可以继续走去其它洞穴,可以选择分组去不同的洞穴。
战士只能往洞穴深处走,不能走回头路
问最多能获得多少金子?

我们可以知道每个节点的花费cost(i) = (x(i)+19)/20。
那么,
f(i, j):表示i子树,用j个战士最多可以获得的价值。
如果i有s个儿子节点,那么就形成了s组的物品,对每组物品进行分组背包。
每一组可以选择派1,2...j-cost(i)个战士去,为什么最多是j-cost(i)?因为还要留下cost(i)个战士消灭当前洞穴的虫子。
这样就可以得到状态转移了:

f(i, j) = max { max{ f(i, j-k) + f(v, k) | 1<=k<=j-cost(i) } |  v是i的儿子节点 }

这题要特别注意的是,如果是叶子节点,并且叶子节点的花费为0,那么要让他的花费变为1,因为必须派一个战士走向叶子节点才可以获得金子.
typedef pair<int, int >PII;
typedef long long int64;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int MAXN = 110;
int n, m;
struct Node {
int num,cost, val;
}room[MAXN];
int f[MAXN][MAXN];
bool vis[MAXN];
vector<int>adj[MAXN];
void dfs(int u) {
vis[u] = true;
memset(f[u], 0, sizeof(f[u]));
// 如果是叶子节点,并且花费为0时,要变成1
if (!room[u].cost && adj[u].size()==1 && u!=1)
room[u].cost = 1;
// 初始化
for (int i = room[u].cost; i <= m; ++i)
f[u][i] = room[u].val;
for (int i = 0; i < adj[u].size(); ++i) {
int v = adj[u][i];
if (vis[v]) continue;
dfs(v);
for (int s = m; s >= room[u].cost; --s) {
for (int j = 1; s-j >= room[u].cost; ++j)
f[u][s] = max(f[u][s], f[u][s-j] + f[v][j]);
}
}
}
int main(){
while (~scanf("%d %d", &n, &m) && n+m != -2) {
for (int i = 1; i <= n; ++i)
adj[i].clear();
for (int i = 1; i <= n; ++i) {
int x;
scanf("%d%d", &x, &room[i].val);
room[i].cost = x/20 + (x%20!=0);
}
for (int i = 0; i < n - 1; ++i) {
int u, v;
scanf("%d %d", &u, &v);
adj[u].push_back(v);
adj[v].push_back(u);
}
if (m==0) {
puts("0");
continue;
}
memset(vis, 0, sizeof(vis));
vis[1] = true;
dfs(1);
printf("%d\n", f[1][m]);
}
return 0;
}
http://www.cnblogs.com/nanke/archive/2012/03/07/2383450.html
分析:树形DP,
需要注意的有俩点:
1)只有通过父节点才可能到达儿子节点,而且,通过父亲节点必须满足人数足够消灭该节点上的所有bugs
2)对于每一棵子树而言,至少要有一个人才可能获得该子树上的brain,即使没有bugs
用dp[i][j]表示派遣j个人到达以i为根的子树所能获得的最大brain值
const int N = 110;
int n,m,dp[N][N],bug[N],p[N];
vector<int> g[N];
bool vis[N];
void init()
{
    memset(vis,false,sizeof(vis));
    memset(dp,0,sizeof(dp));
    for(int i=0;i<=n;i++)
        g[i].clear();
}
void dfs(int u)
{
    vis[u]=true;
    int size=g[u].size();
    int cost=(bug[u]+19)/20;
    if(cost>m) return ;
    for(int i=cost;i<=m;i++)    
        dp[u][i]=p[u];
    for(int i=0;i<size;i++)
    {
        int v=g[u][i];
        if(vis[v])continue;
        dfs(v);
        for(int j=m;j>=cost;j--)//u节点有j人
        {
            for(int k=0;k<=j-cost;k++)//v节点,注意边界,u节点的人数至少为cost,即j-k>=cost
                dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
        }
    }
    if(dp[u][0]>0)//以u为根节点的子树至少要有一个人才可以获得该节点的brain
    {
        dp[u][1]=max(dp[u][1],dp[u][0]);
        dp[u][0]=0;
    }
}
int main()
{
    int x,y;
    while(scanf("%d %d",&n,&m)==2)
    {
        if(n==-1 && m==-1)
            break;
        for(int i=1;i<=n;i++)
            scanf("%d %d",&bug[i],&p[i]);
        init();
        for(int i=1;i<n;i++)
        {
            scanf("%d %d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        if(m==0)//没有人就不可能获得brain
        {
            printf("0\n");
            continue;
        }
        dfs(1);
        int mp=0;
        for(int i=1;i<=m;i++)
            mp=max(mp,dp[1][i]);
        printf("%d\n",mp);
    }
    return 0;
}
Also check code at http://www.2cto.com/kf/201405/299013.html
for(i = 1;i <= n;i++){
scanf("%d%d",&w[i] , &val[i]);
 w[i] = (w[i] + 19)/20;//计算每个结点需要的士兵数
}
hdu-1011- Starship Troopers-自由树转二叉树+树形DP
按照题意,把自由树转为二叉树。
然后树形dp
dp[x][y]:在二叉树中的x节点为根的树中,使用了y个士兵获得的最大值。
dp[x][y]=dp[node[x].l][k]+nval[x]+dp[node[x].r][y-k];
  1. void change(int x)  
  2. {  
  3.     int i,len,a,b;  
  4.     len=old[x].size();  
  5.     vis[x]=1;  
  6.     for(i=0; i<len; i++)  
  7.     {  
  8.         if(vis[old[x][i]])continue;  
  9.         a=x;  
  10.         b=old[x][i];  
  11.         node[b].r=node[a].l;  
  12.         node[a].l=b;  
  13.         change(old[x][i]);  
  14.     }  
  15. }  

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