首页 > 编程语言 >【恐怖の算法】 树形DP

【恐怖の算法】 树形DP

时间:2024-12-07 22:33:31浏览次数:7  
标签:cnt 6005 int head 算法 树形 DP

【恐怖の算法】 树型DP

引入

树形 DP,即在树上进行的 DP。由于树固有的递归性质,树形 DP 一般都是递归进行的。

基础

以下面这道题为例,介绍一下树形 DP 的一般过程。

洛谷P1352 没有上司的舞会

我们设 \(f(i,0/1)\) 代表以 \(i\) 为根的子树的最优解(第二维的值为 \(0\) 代表 \(i\) 不参加舞会的情况,\(1\) 代表 \(i\) 参加舞会的情况)。

对于每个状态,都存在两种决策(其中下面的 \(x\) 都是 \(i\) 的儿子):

上司不参加舞会时,下属可以参加,也可以不参加,此时有 \(f(i,0) = \sum\max \{f(x,1),f(x,0)\}\);

上司参加舞会时,下属都不会参加,此时有 \(f(i,1) = \sum{f(x,0)} + a_i\)。

我们可以通过 \(DFS\),在返回上一层时更新当前结点的最优解。

#include <algorithm>
#include <iostream>
using namespace std;

struct edge {
  int v, next;
} e[6005];

int head[6005], n, cnt, f[6005][2], ans, is_h[6005], vis[6005];

void addedge(int u, int v) {  // 建图
  e[++cnt].v = v;
  e[cnt].next = head[u];
  head[u] = cnt;
}

void calc(int k) {
  vis[k] = 1;
  for (int i = head[k]; i; i = e[i].next) {  // 枚举该结点的每个子结点
    if (vis[e[i].v]) continue;
    calc(e[i].v);
    f[k][1] += f[e[i].v][0];
    f[k][0] += max(f[e[i].v][0], f[e[i].v][1]);  // 转移方程
  }
  return;
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i <= n; i++) cin >> f[i][1];
  for (int i = 1; i < n; i++) {
    int l, k;
    cin >> l >> k;
    is_h[l] = 1;
    addedge(k, l);
  }
  for (int i = 1; i <= n; i++)
    if (!is_h[i]) {  // 从根结点开始DFS
      calc(i);
      cout << max(f[i][1], f[i][0]);
      return 0;
    }
}

通常,树形 \(DP\) 状态一般都为当前节点的最优解。先 \(DFS\) 遍历子树的所有最优解,然后向上传递给子树的父节点来转移,最终根节点的值即为所求的最优解.

噩梦算法の终结~

标签:cnt,6005,int,head,算法,树形,DP
From: https://www.cnblogs.com/yhy2013/p/18592772

相关文章

  • 【Baum-Welch 算法】10.35初始状态分布π的拉格朗日函数对其求偏导数并令结果为0
    本文是将博文【Baum-Welch算法】中的公式单独拿出来做一个详细的解析。公式(10.35)(10.35)(10.35)是用于......
  • 数位DP
    数位DP,要求的数往往极大,常用试填法。求区间[l,r]内满足某某条件的数有多少个。可以用[1,r]的答案-[1,l-1]的答案。往往在记忆化是要记录以下几点:1)从高到低填到第几位2)是否卡着限制3)是否有前导04)题目中的特殊要求例1,例2,例3都是这种题。满足某某条件的第k小的数首先预处理......
  • 【推荐算法】推荐系统中的单目标精排模型
    前言:推荐系统中模型发展较快,初学者【也就是笔者】很难对模型进行一个系统的学习。因此,这篇文章总结了王树森中的视频以及《深度学习推荐系统》中的单目标精排模型,绘制了一个单目标精排模型的思维导图来帮助初学者【笔者】更好的学习。在后面的学习过程中,会加入更多的单目标精排论......
  • 迪克斯特拉算法:单源最短路径问题
    一、迪杰斯特拉算法的介绍迪杰斯特拉(Dijkstra)算法是一种用于计算加权图中单源最短路径的经典算法,由荷兰计算机科学家艾兹赫·迪杰斯特拉(EdsgerDijkstra)于1956年提出。迪杰斯特拉算法的核心思想是通过贪心策略,不断选择当前路径代价最小的节点,并逐步扩展搜索范围,直到找到从源节......
  • 算法刷题打卡DFS深度搜索
    DFS概要:    要想学会深度优先搜索的题目,首先需要知道他的代码原理,适用场景基本原理:    DFS是基于遍历,搜索树,图的算法,通过从根节点(或任意起始节点)开始,沿着每个分支深入访问节点,直到到达叶子节点或没有未访问的邻居节点为止,然后回溯到上一个节点,继续搜索其他......
  • 算法描述:动态规划
    动态规划算法步骤:找出最优解的性质,刻画数据结构递归定义最优值自底向上计算出各子结构的最优值并添入表格中并保存以最优值构造最优解最长公共子序列递归结构:intLCSlength(char*a,char*b,int**len,int**flag)//a,b输入字符串,输出数组len的元素len[i][j]记录len(i,j),//......
  • 算法积累
    计算最大数   对数组进行排序,取最大的n个数和(最大数*(绝对值乘积最大的数)),两者取最大值即为最大数。/***題目:求一个整数数组中的三个数最大乘积*思路:若全是正數,則数组按顺序排序后,最大三个数的乘积即为最大值*若全是负数,同样最大三个数的乘积即......
  • 【特殊子序列 DP】【hard】力扣446. 等差数列划分 II - 子序列
    给你一个整数数组nums,返回nums中所有等差子序列的数目。如果一个序列中至少有三个元素,并且任意两个相邻元素之差相同,则称该序列为等差序列。例如,[1,3,5,7,9]、[7,7,7,7]和[3,-1,-5,-9]都是等差序列。再例如,[1,1,2,5,7]不是等差序列。数组中的......
  • 【推荐算法】推荐系统中的特征工程
    前言:这篇文章是阅读石塔西《互联网大厂推荐算法实战》第二章推荐系统中的特征工程的学习笔记,在未来对于特征向量的学习笔记会在此基础上进行补充。编者认为特征工程已经过时的言论是错误的,该言论认为DNN模型可以自主的完成对数据特征的提取,但是在DeepCrossNetwork网络中,作者直......
  • 欧几里得算法 & 扩展欧几里得算法
    一、欧几里得算法欧几里得算法,也叫辗转相除,简称gcd,用于计算两个整数的最大公约数引理:\(\gcd(a,b)=\gcd(b,a\%b)\)证明:设\(r=a%b\),\(c=gcd(a,b)\)则\(a=xc\),\(b=yc\),其中\(x,y\)互质\(r=a\%b=a-pb=xc-pyc=(x-py)c\)......