树形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,一经查实,立即删除!

相关文章

10秒教会你mysql的连接

连接MySQL数据库通常可以通过多种方法实现&#xff0c;以下是几种常见的方法&#xff0c;我将按照您的要求以清晰、分点的方式归纳说明&#xff1a; 1. 使用MySQL命令行客户端 打开终端或命令提示符&#xff1a;首先&#xff0c;打开您的计算机上的终端或命令提示符窗口。输入…

CSS中的display属性:布局控制的关键

CSS的display属性是控制元素在页面上如何显示的核心属性之一。它决定了元素的显示类型&#xff0c;以及它在页面布局中的行为。本文将详细介绍display属性的不同值及其使用场景&#xff0c;帮助你更好地掌握布局控制。 display属性的基本值 block 特点&#xff1a;块级元素&…

LeetCode每日一题 2734.子串操作后的字典序最小字符串|标志位遍历字符数组

问题描述 &#x1f4cb; 子串操作后的字典序最小字符串 给定一个仅包含小写字母的字符串&#xff0c;你可以执行如下操作任意次&#xff1a; 选择某个子串&#xff0c;将其中的每个字符都替换成其前一个字母&#xff08;比如 ‘b’ 变成 ‘a’&#xff0c;‘c’ 变成 ‘b’&…

未来数据中心智能运维的趋势

随着信息技术的飞速发展&#xff0c;数据中心作为支撑企业信息化建设的核心枢纽&#xff0c;其运维管理的重要性日益凸显。传统的运维模式已难以满足现代数据中心高效、安全、灵活的需求&#xff0c;而智能运维正成为行业发展的新趋势。本文将结合运维行业的资料和团队经验&…

【JavaScript 小工具】——如何判断当前页面是否在微信浏览器中打开

要判断用户是否通过微信浏览器打开网页&#xff0c;你可以检查用户代理&#xff08;User Agent&#xff09;字符串中是否包含微信浏览器的特定标识。微信浏览器通常会在User Agent中包含"MicroMessenger"这个关键词。 以下是一段JavaScript代码示例&#xff0c;用于…

不使用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;只可以匹配多次&…

电镀用开关电源技术详解

1 引言 在电镀行业里&#xff0c;一般要求工作电源的输出电压较低&#xff0c;而电流很大。电源的功率要求也比较高&#xff0c;一般都是几千瓦到几十千瓦。目前&#xff0c;如此大功率的电镀电源一般都采用晶闸管相控整流方式。其缺点是体积大、效率低、噪音高、功率因数低、…

[CocosCreator]CocosCreator网络通信:https + websocket + protobuf

环境 cocos creator版本&#xff1a;3.8.0 开发语言&#xff1a;ts 操作系统&#xff1a;windows http部分 直接使用 XMLHttpRequest 创建http请求 // _getHttpUrl 方法自己写字符串拼接public httpPostJsonRequest(uri: string, headData: any, data: any, cb: Function…

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

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

微信小程序 点击左上角返回弹窗提示

业务需求&#xff1a;当页面表单没有提交直接返回时&#xff0c;要提示用户是否保存当前信息&#xff0c;如果已经提交就不提示了。 由于微信小程序是无法监听右上角按钮返回事件。 所以就换个思路 小程序提供了如下两个Api wx.enableAlertBeforeUnload(Object object)&…

Python入门-基础知识-编程规范

1.缩进 在编程语言中&#xff0c;代码之间往往存在着一定的逻辑关系和层次关系。C语言和Java语言等 用“{}”分隔代码块&#xff0c;而Python用的是缩进和冒号。Python代码的缩进可以使用空格键或 Tab键来实现&#xff0c;通常情况下以4个空格或1个制表符作为1个缩进量。Pytho…

TCP协议中的三次握手和四次挥手机制

TCP协议中的三次握手和四次挥手机制 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的通信协议&#xff0c;它的三次握手和四次挥手机制是建立和断开连接的关键步骤。 三次握手&#xff1a; 第一次…

等保测评与网络安全法规的关联:构建信息安全的法律与技术双重保障

在信息化高速发展的今天&#xff0c;网络安全已经成为国家安全、社会稳定和经济发展的重要基石。为了保障网络空间的安全和稳定&#xff0c;我国制定了一系列网络安全法规&#xff0c;其中最为关键的就是《中华人民共和国网络安全法》。与此同时&#xff0c;等保测评&#xff0…