树形DP——AcWing 323. 战略游戏

树形DP

定义

树形动态规划(Tree Dynamic Programming,简称树形DP)是一种在树形结构上应用动态规划算法的技术。它利用树的递归结构,通过定义状态和状态转移方程,来求解与树相关的最优化问题,如树上的最长路径、最小路径覆盖、最大独立集等。与传统的线性动态规划相比,树形DP更侧重于利用树的子结构特性,递归地解决问题,从叶子节点到根节点或反之进行状态的累积和更新。

运用情况

  1. 树的最长路径问题:给定一个树,找出一条路径,使得该路径上所有边的权值之和最大。
  2. 数字转换问题:在不超过 n 的正整数范围内进行数字变换,求不断进行数字变换且不出现重复数字的最多变换步数。
  3. 树的中心问题:给定一棵树,找到一个点,使得该点到树中其他结点的最远距离最近。
  4. 没有上司的舞会问题:在一棵以校长为根的树中,每个职员有一个快乐指数,且没有职员愿意和直接上司一起参会,求邀请一部分职员参会使得所有参会职员的快乐指数总和最大。
  5. 路径问题:如求解树中两个节点间的最大距离、树的直径等。
  6. 子树问题:找出具有特定性质的子树,如最大权独立集、最小割集等。
  7. 计数问题:统计满足特定条件的子树数量,如完美子树的数量、具有特定性质的路径数量等。
  8. 优化问题:在树上分配资源,使得某个指标最大化或最小化,如最小化涂色成本、最大化收集的资源等。

注意事项

  1. 树形 DP 的 for 循环能优化就优化,比如取 j=min(size(x),m)k<=min(size(x),m) 之类的,否则很容易 TLE。
  2. 要考虑清楚不合法状态是否会对答案产生影响,如果有就要 memset(dp,-1,sizeof(dp)) 和初始化,树形 DP 中跳过 dp(x)(j)=-1 和 dp(x)(k-j)=-1 之类情况。
  3. 状态定义:正确定义状态是关键,通常包括节点的选择状态(是否包含当前节点)和其他与问题相关的附加信息。
  4. 状态转移:明确状态之间的依赖关系,设计合理的状态转移方程,通常从子节点到父节点进行信息传递。
  5. 边界条件:处理好边界情况,如树的叶子节点或只有一个节点的子树。
  6. 记忆化搜索:由于树形DP往往涉及大量的重复计算,使用记忆化搜索可以避免重复计算,提高效率。
  7. 递归/迭代实现:根据具体情况选择合适的实现方式,递归通常更直观,迭代则可能在空间复杂度上有优势。

解题思路

  1. 确定状态表示:需要根据具体问题确定状态表示,通常是以节点为基本单位,记录每个节点的相关信息。
  2. 定义状态转移方程:根据问题的要求,确定状态之间的转移关系,即如何从一个状态转移到另一个状态。
  3. 确定边界条件:明确问题的边界情况,例如根节点的状态或者叶子节点的状态。
  4. 进行递归计算:根据状态转移方程,从根节点开始递归地计算每个节点的状态。
  5. 求解最优解:根据计算得到的状态值,求解问题的最优解。
  6. 分析问题:首先明确问题的求解目标,识别出问题中的“最优子结构”,即问题的解可以由其子问题的解组合得出。
  7. 定义状态:基于问题特点,定义状态表示每个节点或子树在求解过程中的信息,通常包括是否选择该节点、子树的某些属性等。
  8. 设计状态转移方程:根据问题性质,确定状态如何从子树转移到父节点,即如何通过子节点的信息计算出父节点的信息。
  9. 初始化:确定基础情况,如叶子节点的初始状态。
  10. 实现:使用深度优先搜索(DFS)或广度优先搜索(BFS)遍历树,并根据状态转移方程计算每个状态的值,通常使用记忆化或递推实现。
  11. 回溯获取答案:根据最终状态,回溯获得问题的最优解。

AcWing 323. 战略游戏

题目描述

活动 - AcWingAcWing 323. 战略游戏 - AcWing活动 - AcWing

运行代码

#include <iostream>
#include <cstring>
using namespace std;
const int N = 2000, M = 4000;
int h[N], e[M], ne[M], idx;
int n;
int f[N][2];
int st[N];
void add(int a, int b)
{e[idx] = b; ne[idx] = h[a]; h[a] = idx ++;
}
void dfs(int u)
{f[u][1] = 1, f[u][0] = 0;for(int i = h[u]; ~i; i = ne[i]){int j = e[i];dfs(j);f[u][0] += f[j][1];f[u][1] += min(f[j][0], f[j][1]);}
}
int main()
{while(scanf("%d", &n) == 1){memset(h, -1, sizeof h);memset(st, 0, sizeof st);idx = 0;for(int i = 0; i < n; i ++ ){int id, cnt;scanf("%d:(%d)", &id, &cnt);while(cnt --){int ver;scanf("%d", &ver);add(id, ver);st[ver] = true;}}int root = 0;while(st[root]) root ++;dfs(root);printf("%d\n", min(f[root][0], f[root][1]));}return 0;
}

代码思路

  1. 数据结构定义:

    • 使用邻接表表示树结构,其中h[N]是头节点数组,e[M]是边的终点数组,ne[M]是下一个兄弟节点的索引数组,idx用于记录当前使用的边的索引。
    • f[N][2]是一个二维状态数组,其中f[u][0]表示以节点u为根的子树中选择不包含该节点的方案数,f[u][1]表示包含该节点的方案数。
    • st[N]标记数组,用来记录某个节点是否已被其他节点直接连接过,辅助找到树的根节点。
  2. 输入处理:

    • 读取整数n表示节点数量。
    • 接收每行输入,格式为“节点ID:(直接子节点数量) 子节点1 子节点2 ...”,并构建邻接表表示的树结构。
  3. 寻找根节点:通过遍历st[]数组找到没有直接父节点的节点作为树的根,初始化为0。

  4. 深度优先搜索(DFS):

    • 从根节点开始进行深度优先搜索,递归遍历整棵树。
    • 对于每个节点u,先假设自己不被选中(f[u][1]=1,表示以自己为根的子树至少有一种情况是选中自己的),不选中父节点的方案数默认为0(f[u][0]=0)。
    • 遍历所有子节点,递归调用DFS更新f[u][0]f[u][1]的值。f[u][0] += f[j][1]意味着考虑不选当前节点时,子节点可选择不包含自己的方案数累加;f[u][1] += min(f[j][0], f[j][1])则是考虑选当前节点时,子节点可以自由选择是否包含自己,取最小值是因为我们要找的是最小方案数。
  5. 输出结果:最终,输出根节点的f[root][0]f[root][1]中的最小值,即为满足条件的最小方案数。

改进思路

  1. 增加注释:提高代码的可读性,特别是对于复杂逻辑的部分,通过注释说明每段代码的目的。
  2. 变量命名清晰:使变量名更具描述性,便于理解每个变量的用途。
  3. 常量分离:将数组大小等硬编码的常量提取为定义在顶部的常量,便于维护和修改。
  4. 函数封装:将部分功能(如读取树的构建)封装成独立的函数,提高代码模块化。
  5. 去除全局变量的过度依赖:尽量减少全局变量的使用,使用函数参数传递必要信息。62.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/36928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不使用cmake,如何在vs2019对cpp项目进行文件夹分类?

不使用cmake&#xff0c;如何在vs2019对cpp项目进行文件夹分类&#xff1f; 1.不使用cmake的根目录指的是哪里&#xff1f;2.什么时候进行项目管理&#xff1f;3.应该分成什么样的文件夹&#xff1f;4.如何分类&#xff1f; 1.不使用cmake的根目录指的是哪里&#xff1f; 查看项…

最新AI智能聊天对话问答系统源码(图文搭建部署教程)+AI绘画,文生图,TTS语音识别输入,文档分析

一、人工智能语言模型和AI绘画在多个领域广泛应用 人工智能语言模型和AI绘画在多个领域都有广泛的应用。以下是一些它们的主要用处&#xff1a; 人工智能语言模型 内容生成 写作辅助&#xff1a;帮助撰写文章、博客、报告、剧本等。 代码生成&#xff1a;自动生成或补全代码&…

sudo: /etc/init.d/ssh: command not found

在 WSL 中尝试启动 SSH 服务时遇到 sudo: /etc/init.d/ssh: command not found 错误 安装 OpenSSH 服务器 更新软件包列表 sudo apt update安装 OpenSSH 服务器 sudo apt install openssh-server启动 SSH 服务 在 WSL 2 上,服务管理与传统 Linux 系统有所不同。你可以手动启动…

C++之STL(十)

1、适配器 2、函数适配器 #include <iostream> using namespace std;#include <algorithm> #include <vector> #include <functional>bool isOdd(int n) {return n % 2 1; } int main() {int a[] {1, 2, 3, 4, 5};vector <int> v(a, a 5);cou…

ONLYOFFICE 8.1版本桌面编辑器测评:重塑办公效率的巅峰之作

在数字化办公日益普及的今天&#xff0c;一款高效、便捷且功能强大的桌面编辑器成为了职场人士不可或缺的工具。ONLYOFFICE 8.1版本桌面编辑器凭借其卓越的性能和丰富的功能&#xff0c;成功吸引了众多用户的目光。今天&#xff0c;我们将对ONLYOFFICE 8.1版本桌面编辑器进行全…

使用el-amap-info-window遇到的问题

使用的这个库https://github.com/yangyanggu/vue-amap 想要滚动amapInfoWindow里的内容&#xff0c;但不触发地图缩放 默认滚动amapInfoWindow里的内容&#xff0c;会触发地图缩放。看了C站一个大佬的文章解决了。 amapInfoWindow会自动滚动到顶部 我的amapInfoWindow里面用了…

【智能制造-4】机器人控制器

机器人控制器中分哪几个模块&#xff1f; 机器人控制器通常由以下几个主要模块组成: 运动控制模块: 负责机器人各轴电机的位置、速度、加速度等控制 实现机器人末端执行器的精确定位和运动控制传感器接口模块: 负责机器人各种传感器信号的采集和处理 为运动控制、环境感知等提…

Python-正则表达式

目录 一、打开正则表达式 二、正则表达式的使用 1、限定符 &#xff08;1&#xff09;x*&#xff1a;*表示它前面的字符y 可以有0个或多个&#xff1b; &#xff08;2&#xff09;x&#xff1a;表示它前面的字符可以出现一次以上&#xff1b;&#xff08;只可以匹配多次&…

2024年6月大众点评深圳餐饮店铺POI分析18万家

2024年6月大众点评深圳餐饮店铺POI共有178720家 店铺POI点位示例&#xff1a; 店铺id G9TSD2JvdLtA7fdm 店铺名称 江味龙虾馆(南山店) 十分制服务评分 8.8 十分制环境评分 8.8 十分制划算评分 8.6 人均价格 128 评价数量 12840 店铺地址 南山大道与桂庙路交叉口西北角…

RAG开发中常见的12个痛点及解决方案

受到 Barnett 等人论文《构建检索增强生成系统的七大挑战》启发&#xff0c;本文将探讨论文中提及的七大挑战及在开发 RAG&#xff08;检索增强生成&#xff09;流程中常遇到的五个额外难题。更为重要的是&#xff0c;我们将深入讨论解决这些 RAG 难题的策略&#xff0c;以便我…

使用 WebGL 创建 3D 对象

WebGL Demohttps://mdn.github.io/dom-examples/webgl-examples/tutorial/sample5/index.html 现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 gl.drawElements() 使用顶点数组列表来替换之前的通过方法gl.drawArrays() 直接…

检测SD NAND文件系统异常和修复的方法

目录 1、打开命令提示符&#xff1a; 2、运行chkdsk命令&#xff1a; 3、命令参数说明&#xff1a; chkdsk是Windows中的一个命令行工具&#xff0c;用于检查磁盘上的文件系统错误和修复坏块。MK米客方德为您提供指导&#xff0c;以下是使用chkdsk的步骤&#xff1a; 1、打开…

综合IT运维管理解决方案

综合IT运维管理解决方案 在信息化和数字化高速发展的时代&#xff0c;企业的IT运维管理已经成为保障业务连续性和提升运营效率的关键环节。高效的IT运维管理不仅能够降低运维成本&#xff0c;还能提升服务质量和用户满意度。本文将详细介绍综合IT运维管理解决方案&#xff0c;…

eBPF技术揭秘:DeepFlow如何引领故障排查,提升运维效率

DeepFlow 实战&#xff1a;eBPF 技术如何提升故障排查效率 目录 DeepFlow 实战&#xff1a;eBPF 技术如何提升故障排查效率 微服务架构系统中各个服务、组件及其相互关系的全景 零侵扰分布式追踪&#xff08;Distributed Tracing&#xff09;的架构和工作流程 关于零侵扰持…

华为od 2024 | 什么是华为od,od 薪资待遇,od机试题清单

目录 专栏导读华为OD机试算法题太多了&#xff0c;知识点繁杂&#xff0c;如何刷题更有效率呢&#xff1f; 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

Spring Session将HttpSession保存到Redis中,实现重启应用会话不丢失

这篇文章介绍一下在springboot项目中整合Spring Session&#xff0c;将session会话信息保存到Redis中&#xff0c;防止重启应用导致会话丢失。 第一步 创建一个springboot项目&#xff0c;添加spring-session-redis的依赖&#xff0c;因为要用到reids&#xff0c;所以要把redi…

扩散模型中的UNET

目录 一、为什么UNET模型可以用于去噪网络二、扩散模型中的UNET是一个条件去噪网络&#xff0c;怎么实现的三、UNET用于分割和用去去噪的区别 一、为什么UNET模型可以用于去噪网络 下采样部分: 能够提取图像的深层次特征&#xff0c;这些特征往往包含图像的重要结构和信息&…

原型开发:加速需求验证与设计优化

目录 前言1. 原型开发的意义1.1 定义与概述1.2 原型的类型 2. 原型开发的优势2.1 明确需求2.2 提升用户满意度2.3 降低开发风险 3. 原型开发的挑战3.1 过多的原型开发3.2 资源投入与管理3.3 期望管理 4. 优化原型开发流程4.1 明确目标与范围4.2 选择合适的工具和方法4.3 加强用…

【MySQL基础篇】概述及SQL指令:DDL及DML

数据库是一个按照数据结构来组织、存储和管理数据的仓库。以下是对数据库概念的详细解释&#xff1a;定义与基本概念&#xff1a; 数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 数据库不仅仅是数据的简单堆积&#xff0c;而是遵循一定的规则…

C++之STL(十一)

1、迭代器适配器 2、插入迭代器 #include <iostream> #include <vector> #include <algorithm> #include <list> using namespace std;void showVec(const vector<int>& v) {for (vector<int>::const_iterator it v.begin(); it ! v.…