博客
关于我
2008GDSOI 鱼肉炸弹(树形dp)
阅读量:597 次
发布时间:2019-03-12

本文共 2497 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们使用树状动态规划(DP)的方法。这是一种高效地处理树结构问题的技术,特别适用于分割问题。以下是详细的思路和方法:

树状动态规划

  • 树的构建

    • 根据建筑的高度,将建筑按照高度建立一棵树,根节点是最高的建筑。每个节点的左子树是左边比它矮的建筑,右子树是右边比它矮的建筑。
  • 动态规划定义

    • f[root][k] 表示以根节点为根的子树,使用最多 k 枚炸弹的情况下,被看守数量的最大值的最小值。
  • 动态规划转移

    • 对于每个节点,考虑在它的左子树和右子树使用一定数量的炸弹,并在根节点使用一枚炸弹的情况,计算最优解。
    • 左右子树的解可以合并,得到当前节点的解。
  • 代码实现

    以下是代码实现,包括树的构建和动态规划部分:

    #include 
    #include
    #include
    using namespace std;struct Node { int l, r;};ll build(ll l, ll r) { if (l > r) return -1; if (l == r) return l; ll max_h = 0, root = l; for (ll i = l; i <= r; ++i) { if (h[i] > max_h) { max_h = h[i], root = i; } } int mid = (l + r) >> 1; Node left = build(l, mid); Node right = build(mid + 1, r); return root;}void tree_dp(ll root, int k) { // 初始化当前根为-1(未访问) if (root == -1) return; // 已访问过根节点 vis[root] = true; // 访问左子树并处理 if (left[root] != -1) { tree_dp(left[root], k); } // 访问右子树并处理 if (right[root] != -1) { tree_dp(right[root], k); } // 对当前根节点进行 DP for (int i = 0; i <= k; ++i) { for (int j = 0; j <= k - i; ++j) { // 情况一:不在根使用炸弹 if (f[left[root]][i] != 0 && f[right[root]][j] != 0) { int max_val = max(f[left[root]][i], f[right[root]][j]); f[root][i + j] = min(f[root][i + j], max_val + c[root]); // 情况二:在根使用一枚炸弹,i + j + 1 <= k if (i + j + 1 <= k) { f[root][i + j + 1] = min(f[root][i + j + 1], max(f[left[root]][i], f[right[root]][j])); } } } // 情况二:在根使用一枚炸弹 if (f[left[root]][0] == 0 && f[right[root]][0] == 0) { // 左右子树最小值为0,或者可以合并 for (int j = 0; j <= k - 1; ++j) { int max_val = max(f[left[root]][j], f[right[root]][j]); if (f[root][j + 1] > max_val + c[root]) { f[root][j + 1] = max_val + c[root]; } } } }}int main() { // 初始化 vector
    h(n + 1), c(n + 1); read(h, c); // 构建树 root = build(1, n); // DP数组初始化 vector
    > f(2, vector
    (k + 1, MAX)); f[0][0] = 0; tree_dp(root, k); cout << f[root][k] << endl; return 0;}

    内容说明

  • 树的构建:使用递归函数从左到右构建树。每个节点找到当前区间内的最大高度作为根,分裂成左右子树。
  • 动态规划处理:通过递归访问每个节点,处理左右子树,并根据炸弹数分割,最终合并左右子树的结果。
  • 处理每个节点:计算所有可能的炸弹分配方案,更新当前节点的最优解并记录结果。
  • 这种方法利用树的结构,减少了复杂度,使得问题变得可控,适用于大规模数据。树状DP能够有效地处理分割问题,且保证了计算的高效性。

    转载地址:http://mvnxz.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置参数中文说明
    查看>>
    nginx配置域名和ip同时访问、开放多端口
    查看>>
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>
    NHibernate学习[1]
    查看>>
    NHibernate异常:No persister for的解决办法
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
    查看>>
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>