zoukankan      html  css  js  c++  java
  • HDU 4044 GeoDefense

    树形DP,和背包差不多。dp[now][x]表示now这个节点的子树上,花费为x的时候,获得的最大防御能力(保证敌方HP<=0)

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 1000 + 10;
    int T, n, m;
    vector<int>tree[maxn];
    struct kind
    {
        int price;
        int power;
        kind(int a, int b){ price = a; power = b; }
    };
    vector<kind>v[maxn];
    bool vis[maxn];
    int dp[maxn][200 + 10];
    int flag[200 + 10], tmp[200 + 10];
    
    void init()
    {
        for (int i = 0; i <= n; i++) tree[i].clear();
        for (int i = 0; i <= n; i++) v[i].clear();
        memset(vis, 0, sizeof vis);
        memset(dp, -1, sizeof dp);
    }
    
    void read()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n - 1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            tree[u].push_back(v);
            tree[v].push_back(u);
        }
        scanf("%d", &m);
    
        for (int i = 1; i <= n; i++)
        {
            int ki;
            scanf("%d", &ki);
            while (ki--)
            {
                int pricei, poweri;
                scanf("%d%d", &pricei, &poweri);
                kind k(pricei, poweri);
                v[i].push_back(k);
            }
        }
    }
    
    void dfs(int now)
    {
        bool fail = 1;
        for (int i = 0; i<tree[now].size(); i++)
            if (!vis[tree[now][i]]) fail = 0;
    
        if (fail)
        {
            for (int i = 0; i<v[now].size(); i++)
                dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
            return;
        }
    
        bool d[maxn];
        memset(d, 0, sizeof d);
        for (int i = 0; i<tree[now].size(); i++)
        {
            if (vis[tree[now][i]]) continue;
    
            int id = tree[now][i];
            vis[id] = 1; dfs(id); d[i] = 1;
        }
    
        memset(flag, -1, sizeof flag);
    
        bool first = 1;
    
        for (int i = 0; i<tree[now].size(); i++)
        {
            if (!d[i]) continue;
    
            int id = tree[now][i];
    
            if (first)
            {
                first = 0;
                for (int j = 0; j <= m; j++) flag[j] = dp[id][j];
            }
    
            else
            {
                memset(tmp, -1, sizeof tmp);
                for (int j = 0; j <= m; j++)
                    for (int k = 0; k <= m; k++)
                        if (dp[id][j] != -1 && flag[k] != -1 && j + k <= m)
                            tmp[j + k] = max(tmp[j + k], min(dp[id][j], flag[k]));
                for (int j = 0; j <= m; j++) flag[j] = tmp[j];
            }
        }
    
        for (int i = 0; i<v[now].size(); i++)
            for (int j = m; j >= v[now][i].price; j--)
                if (flag[j - v[now][i].price] != -1)
                    dp[now][j] = max(dp[now][j], flag[j - v[now][i].price] + v[now][i].power);
    
        for (int i = 0; i <= m; i++) dp[now][i] = max(dp[now][i], flag[i]);
    
        for (int i = 0; i<v[now].size(); i++)
            dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
    }
    
    void work()
    {
        vis[1] = 1;
        dfs(1);
        int ans = 0;
        for (int i = 0; i <= m; i++) ans = max(ans, dp[1][i]);
        printf("%d
    ", ans);
    }
    
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            init();
            read();
            work();
        }
        return 0;
    }
  • 相关阅读:
    mysql死锁问题分析
    你应该知道的RPC原理
    如何健壮你的后端服务?
    如何用消息系统避免分布式事务?
    一个故事讲清楚NIO
    地图匹配实践
    利用模拟退火提高Kmeans的聚类精度
    大数据并行计算利器之MPI/OpenMP
    GPU---并行计算利器
    如何设计实现一个地址反解析服务?
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5186148.html
Copyright © 2011-2022 走看看