zoukankan      html  css  js  c++  java
  • Hdu 1011 Starship Troopers 树形dp

    又是一道树状dp题目,感觉好难,看的网上的解析才做出来,不过比第一次遇到这种题目时要好多了,加油,多遇到几次就会了。

    代码:

    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int MAX = 105;
    
    int dp[MAX][MAX];
    int bug[MAX], brain[MAX];
    int n, m;
    int vis[MAX]; 
    vector<int> tree[MAX];        //
    
    void dfs(int root);
    
    int main(){
    //    freopen("input.txt", "r", stdin);
        
        while(cin >> n >> m && n != -1){
            for(int i=1; i<=n; i++){
                cin >> bug[i] >> brain[i];
                bug[i] = (bug[i] + 19) / 20;    //转化为需要消耗多少战士,向上取整
                tree[i].clear(); 
            }
            for(int i=1; i<n; i++){
                int u, v;
                cin >> u >> v;
                tree[u].push_back(v);
                tree[v].push_back(u);
            }
            
            if(m == 0){
                cout << 0 << endl;    continue;
            }
            
            memset(vis, 0, sizeof(vis));
            memset(dp, 0, sizeof(dp));
            dfs(1);
            
            cout << dp[1][m] << endl;
        }
        
        return 0;
    } 
    
    void dfs(int root){
        vis[root] = 1;
        
        if(m < bug[root])
            return;
        
        for(int i=bug[root]; i<=m; i++){
            dp[root][i] = brain[root];        //当军队数大于等于bug[root],则至少可以获取到 brain [root] 的大脑 
        }
        
        for(int i=0; i<tree[root].size(); i++){
            int v = tree[root][i];
            if(vis[v])            //区分根结点与子节点,v 一定是当前树的祖先 
                continue;
            dfs(v);            //将子树的状态数组填充好 
            //DP,在root中 k 个战士,子树中  j-k 个战士时的最大值,k从bug[root]到 m
            for(int j=m; j>=bug[root]; j--){    //背包容量为 j 时 
                for(int k=j-1; k>=bug[root]; k--){    //root 这颗树 k 个战士 
                    //如果放第 i 棵子树,则脑量等于包括root和前面 i-1 棵子树 k 个战士获取的最大脑量加上第 i 棵子树能获取的最大脑量
                    dp[root][j] = max(dp[root][j], dp[root][k] + dp[v][j-k]); 
                }
            } 
        }
    }
  • 相关阅读:
    MFC深入浅出读书笔记第一部分
    给对话框添加背景
    相对路径与绝对路径之比较
    线程同步的四种方式以及串口通信
    DirectShow简单入门程序
    两个对话框之间的通信
    websphere部署war包
    Struts2的基础知识
    iBatis基础知识
    Struts1的基础知识
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/7256765.html
Copyright © 2011-2022 走看看