zoukankan      html  css  js  c++  java
  • HDU_1011 Starship Troopers && HDU_1561 The more, The Better (树型dp)

      这两道题很类似,先说第一道题。定义dp[i][j]表示根结点为i时,用掉j个士兵得到的最大possible。

    dp[i][j] = max(dp[i][j], dp[i][j-k] + dp[son[i]][k]);

    递归的求出dp[son[i]][k]的值。最后结果就是dp[1][m];

    用临界矩阵存图。

    核心代码:

    void dfs(int root) {
        int i, j, k, child, len;
        vis[root] = true;
        for(i = tree[root].bugs; i <= m; i++) {
            dp[root][i] = tree[root].p;
        }
        len = g[root].size();
        for(i = 0; i < len; i++) {
            child = g[root][i];
            if(!vis[child]) {
                dfs(child);
                for(j = m; j >= tree[root].bugs; j--)
                    for(k = 1; k + j <= m; k++)
                        dp[root][j+k] = max(dp[root][j+k], dp[root][j] + dp[child][k]);
            }
        }
    }



    第二题跟第一题一样,不过它是以0为根结点,而0上没有权值。所以根为0时单独处理一下。转移方程跟上面一样:

    核心代码:

    void dfs(int r) {
        int i, j, k, len, c;
        vis[r] = true;
        for(i = 1; i <= m; i++) {
            dp[r][i] = p[r];
        }
        if(r == 0)    dp[r][0] = p[r];
        len = g[r].size();
        for(i = 0; i < len; i++) {
            c = g[r][i];
            if(!vis[c]) {
                dfs(c);
                for(j = m; j >= (r == 0 ? 0 : 1); j --) {
                    for(k = 1; k + j <= m; k++) {
                        if(dp[c][k] != -1 && dp[r][j] != -1) {
                            dp[r][j + k] = max(dp[r][j+k], dp[r][j] + dp[c][k]);
                        }
                    }
                }
            }
        }
    }
  • 相关阅读:
    创建索引
    异常处理之ThreadException、unhandledException及多线程异常处理
    Extjs ComboBox常用的配置
    制作Visual Studio项目模板
    wince更改桌面
    创建链接服务器
    IP查询接口
    软件工程未来发展趋势
    在SQL Server数据库开发中的十大问题
    .NET 2.0中的企业库异常处理块
  • 原文地址:https://www.cnblogs.com/vongang/p/2314217.html
Copyright © 2011-2022 走看看