hdu 4044 GeoDefense (树形dp+01背包)

GeoDefense

Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 663    Accepted Submission(s): 267

Problem Description

Tower defense is a kind of real-time strategy computer games. The goal of tower defense games is to try to stop enemies from reaching your bases by building towers which shoot at them as they pass.

The choice and positioning of the towers is the essential strategy of the game. Many games, such as Flash Element Tower Defense, feature enemies that run through a "maze", which allows the player to strategically place towers for optimal effectiveness. However,
some versions of the genre force the user to create the maze out of their own towers, such as Desktop Tower Defense. Some versions are a hybrid of these two types, with preset paths that can be modified to some extent by tower placement, or towers that can
be modified by path placement.

geoDefense is a Thinking Man’s Action Tower Defense. It has become one of "PC World‘s 10 iPhone Games You CANNOT Live Without". Using exciting vectorized graphics, this highly kinetic game brings a whole new dimension to the defense genre. Devastate creeps
with blasters, lasers and missiles and watch their energy debris swirl through the gravity wells of your vortex towers.

There is a geoDefense maze of n points numbered from 1 and connected by passageways. There are at least two dead ends among these n points, and there is always one and only one path between any pair of points. Point 1 is a dead end, and it’s the base of enemies,
and all the other dead ends are your bases.

To prevent the enemy reaching your bases, you have to construct towers to attack the enemy. You can build tower on any point and you can only build one tower on one point. A tower can only shot the enemy when it passes the tower. You are given ki choices to
build tower on point i, and each choice is given in the format of (price, power) which means that you can build a tower with attack power value equals power in the cost of price. You can also build nothing on a point so it will not cost your money. A tower
will reduce the enemy’s HP by its attack power. When the HP is less or equal to zero, the enemy dies immediately.

The base of enemies will release only one enemy. It moves very fast that you cannot do anything such as building towers while it is running. It runs all the way until it dies or reaches one of your bases. However, you cannot predict the route it will go through.
To win the game, you must kill the enemy before it reaches your bases. You have to strategically place towers for optimal effectiveness so that the fortifications are steady enough to protect the bold and powerful enemy with high HP. You are troubling your
head on figuring out the highest HP of the enemy you are able to kill on the way certainly. You have money m when the game begins.

Please note that the towers build in the enemy’s base or your bases are all effective and if the enemy is shot to death in your bases, you still win.

Input

The input consists of several test cases. The first line is an integer T (1 <= T <= 20), which shows the number of the cases.

For each test case, the first line contains only one integer n (2 <= n <= 1000) meaning the number of points.

The following n-1 lines describe the passageways. Each line contains two integers u and v, which are the endpoints of a passageway.

The following line contains only one integer m (1 <= m <= 200) meaning the amount of your money when the game begins.

Then n lines follow. The ith line describes the construction choices of the ith point. It starts with an integer ki (0 <= ki <= 50) and ki is followed by ki pairs of integers separated by spaces. The jth pair is (pricei,j, poweri,j), 0 <= pricei,j <= 200, 0
<= poweri,j <= 50000. ki being zero means that you can’t build a tower on the ith point.

Output

For each test case, output a line containing the highest HP value of your enemy that you can deal with. It means that if your enemy’s HP is larger than that highest value, you can’t guarantee your victory.

Sample Input

2
2
1 2
30
3 10 20 20 40 30 50
3 10 30 20 40 30 45
4
2 1
3 1
1 4
60
3 10 20 20 40 30 50
3 10 30 20 40 30 45
3 10 30 20 40 30 35
3 10 30 20 40 30 35

Sample Output

70
80

Source

The 36th ACM/ICPC Asia Regional
Beijing Site —— Online Contest

题意:(copy的别人的)

这是一个塔防游戏,地图是一个n个编号为1~n的节点的树, 节点1是敌人的基地,其他叶子节点都是你的基地。敌人的基地会源源不断地出来怪兽,为了防止敌人攻进你的基地,你可以选择造塔。每个节点最多只能造一个塔,且节点i可以有ki种塔供你选择,价钱和攻击力分别为price_i, power_i,攻击力power_i,效果是让敌人经过这个节点时让敌人的血减少power_i点。那么从敌人的基地到你的任意一个叶子基地的路径,这条路径上的所有塔的攻击力之和,就是这个基地的抵抗力。敌人的攻击路径是不确定的,为了保护你的所有基地,你要确定所有基地中抵抗力最低的一个。 你只有数量为m的钱,问最佳方案,可以抵挡敌人的最大血量是多少?也就是,让所有叶子基地中抵抗力最低的一个的值尽量大,最大是多少?

思路:

树形dp,dp[u][j]表示到达u点还有j块钱的最大攻击力,那么将j分配给孩子,取孩子的最小值,取分配方案的最大值就行了,因为每个点都可以建塔,所以更新树形更新完dp[u][j]后再01背包放哪个塔来更新,注意price可以为0,就是被这个已经知道的存在的track坑了好久。衰~

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#include <sstream>
#define maxn 1005
#define MAXN 100005
#define mod 100000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
using namespace std;

int n,m,ans,cnt,tot,flag;
int dp[maxn][205],head[maxn];
int num[maxn],cost[maxn][55],val[maxn][55];
struct node
{
    int v,w,next;
}edge[10005];

void addedge(int u,int v,int w)
{
    cnt++;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int u,int fa)
{
    dp[u][0]=INF;
    int i,j,k,v,t;
    for(i=head[u];i;i=edge[i].next)
    {
        v=edge[i].v;
        if(v==fa) continue ;
        dfs(v,u);
        for(j=m;j>=0;j--)
        {
            t=0;
            for(k=0;k<=j;k++)
            {
                t=max(t,min(dp[v][k],dp[u][j-k]));
            }
            dp[u][j]=t;
        }
    }
    if(dp[u][0]==INF) dp[u][0]=0;  // 一定要加这个判断
    for(j=m;j>=0;j--)
    {
        t=dp[u][j];
        for(i=1;i<=num[u];i++)
        {
            if(j>=cost[u][i])
            {
                t=max(t,dp[u][j-cost[u][i]]+val[u][i]);
            }
        }
        dp[u][j]=t;
    }
}
int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int u,v;
        cnt=0;
        memset(head,0,sizeof(head));
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v,0);
            addedge(v,u,0);
        }
        scanf("%d",&m);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            for(j=1;j<=num[i];j++)
            {
                scanf("%d%d",&cost[i][j],&val[i][j]);
            }
        }
        memset(dp,0,sizeof(dp));
        dfs(1,0);
        printf("%d\n",dp[1][m]);
    }
    return 0;
}
/*
20
4
2 1
3 1
1 4
30
0
1 10 30
1 10 12
1 20 3
9
1 2
1 4
1 3
1 5
3 6
3 7
5 8
5 9
100
2 50 40 20 30
1 10 20
1 30 15
1 20 20
1 10 11
1 20 100
1 10 100
1 10 80
1 5 10
3
1 2
2 3
30
1 10 20
1 10 20
1 10 20
*/

hdu 4044 GeoDefense (树形dp+01背包)

时间: 2024-10-05 03:35:31

hdu 4044 GeoDefense (树形dp+01背包)的相关文章

HDU ACM 4044 GeoDefense -&gt;树形DP+分组背包

题意:地图是一个编号为1-n的节点的树,节点1是敌方基地,其他叶节点是我方基地.敌人基地会出来敌人,为了防止敌人攻进我方基地,我们可以选择造塔.每个节点只能造一个塔,节点i有ki种塔供选择,价值和攻击力为price_i, power_i,攻击力power_i是让敌人经过这个节点时让敌人的HP减少power_i点.因此从敌人基地到我方任意一个基地的路径,这条路径上所有塔的攻击力之和,就是这个基地的抵抗力. 敌人攻击路径不确定,为了保护我方所有基地,需要确定所有基地中抵抗力最低的一个.我方只有数量为

hdu 1561The more, The Better(树形dp&amp;01背包)

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4949    Accepted Submission(s): 2918 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

poj 3345 Bribing FIPA 【树形dp + 01背包】

Bribing FIPA Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4274   Accepted: 1337 Description There is going to be a voting at FIPA (Fédération Internationale de Programmation Association) to determine the host of the next IPWC (Interna

hdu 1561 树形dp+0-1背包

1 /* 2 根据先后关系,可以建立一棵树 3 dp[i][j]表示第i个节点选j个的最大值 4 dp[i][j]=max(sigma(dp[c[i][ki]])) 5 sigma(dp[c[i][ki]])表示从i的儿子节点中一共选取j个点的最大值 6 */ 7 /*#include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 #include <vector> 11 using names

poj 1947(树形DP+01背包)

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10663   Accepted: 4891 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. Th

hihoCoder1055.刷油漆——树形Dp+01背包

http://hihocoder.com/problemset/problem/1055 一棵有根树,包含根节点1,选择M个连续的节点,使得权值最大 dp[u][j] 表示以i为根的子树中,选择包含根节点的j个连续节点所能获得的最大权值 枚举子节点选择的个数,儿子节点选择的个数,当做01背包 #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include

hihoCoder#1055 : 刷油漆 (树形DP+01背包)

题目大意:给一棵带点权的树,现在要从根节点开始选出m个连通的节点,使总权值最大. 题目分析:定义状态dp(u,m)表示在以u为根的子树从根节点开始选出m个点连通的最大总权值,则dp(u,m)=max(dp(u,m),dp(u,m-k)+dp(son,k)),其中0<=k<m.这是01背包,k应该从大往小枚举. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<v

hdu 1561 The more, The Better(树形dp+01背包)

The more, The Better Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡.你能帮ACboy算出要获得

HDU 2602 Bone Collector DP(01背包)

Bone Collector Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , c