HDU

来源:互联网 发布:淘宝卖家销量排行榜 编辑:程序博客网 时间:2024/06/11 20:05

HDU - 4044传送门

  题意:给一棵树,树根一定是1,敌人在1位置,每个叶子节点是你的基地,每个节点(包括1节点和你的基地)可以建一个防御塔,每个节点有多种防御塔供你选择,告诉你每种防御塔的价钱和防御能力。你现在有m这么多钱,你可以所有节点上建塔,每个节点只能建一个或不建塔。敌人很聪明,它会去摧毁防御最弱的路线(路线上所有点的防御能力之和)的基地。问你防御最弱的路线防御能力的最大值可以是多少?

思路:树形DP,从根节点开始状态转移,对于节点x,先同过分组背包计算出当前用费应j所得到的最大伤害(要求儿子节点中最小伤害那一个),用01背包加上在x点放置炮台,所得到的费用j的最大伤害。

注意:当一个炮台的费用为0时,不能用简单的背包解决,要加一个tem,具体看代码。

#include<cstdio>#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<cstring>using namespace std;const int INF=0x3f3f3f3f;const int N=6100;bool vis[N];int n,m,dp[N][1033];vector<int> a[1055],b[1055],g[N];void dfs(int x){    vis[x]=true;    dp[x][0]=INF; //后面求所有子节点最小值时,当放置第一个炮台,利用min得到第一个节点炮台的值,第二个节点会被自动清零(如果有的话)    for(int i=0;i<g[x].size();i++)    {        int y=g[x][i];        if(vis[y])continue;         dfs(y);         for(int v=m;v>=0;v--)        {            int tem=0;            for(int j=0;j<=v;j++)            tem=max(tem,min(dp[x][v-j],dp[y][j]));            dp[x][v]=tem;        }    }    if(dp[x][0]==INF)dp[x][0]=0;    for(int v=m;v>=0;v--)    {                int tem=dp[x][v];        for(int i=0;i<a[x].size();i++)            if(v>=a[x][i])        tem=max(tem,dp[x][v-a[x][i]]+b[x][i]);//如果炮台造价为0,则dp[x][v]的值不但在变,会得到错误的答案        dp[x][v]=tem;    }}int main(){    int ta,x,y,z;    scanf("%d",&ta);    while(ta--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)            g[i].clear();        for(int i=1;i<n;i++)        {            scanf("%d%d",&x,&y);            g[x].push_back(y);            g[y].push_back(x);        }        scanf("%d",&m);        for(int i=1;i<=n;i++)        {            a[i].clear();            b[i].clear();            scanf("%d",&x);            while(x--)            {                scanf("%d%d",&y,&z);                a[i].push_back(y);                b[i].push_back(z);            }        }        memset(vis,false,sizeof(vis));        memset(dp,0,sizeof(dp));        dfs(1);        int ans=dp[1][m];        printf("%d\n",ans);    }    return 0;}


原创粉丝点击