树形dp瞎讲+树形dp基础题题解
---恢复内容开始---
没错
咕了这么久(没有青青姐久
我又开始写博客了( ´▽`)
想了很久些什么(才没有想过呢
虽然被鄙视基础不好但还是走上了树形dp的不归路
那么
就来写写树形dp吧(dtx daolao不要打我
树形dp是什么呢?
一言概之,dfs中的动态规划
emmmmm
对
因为没什么固定格式
就推转移方程(所以我一开始根本找不到讲树形dp的blog
然后发现了良心博客一枚
放一下链接
基本的dp方程
选择节点类
dp[i][0]=dp[j][1]dp[i][1]=max/min(dp[j][0],dp[j][1]){dp[i][0]=dp[j][1]dp[i][1]=max/min(dp[j][0],dp[j][1])树形背包类
dp[v][k]=dp[u][k]+valdp[u][k]=max(dp[u][k],dp[v][k−1])
虽然关于树形dp的博客基本上都是题
但是看懂了基本dp方程,理解了实质大概就不会特别难(我这句话真严谨
然后
题还是有很多的
就不放题面了
放链接好了
(要是放一堆图片有假装写了很多的嫌疑
传送门——>luogu P1352 没有上司的舞会
核心的代码就是上边放的状态转移方程
#include<cstdio> #include<algorithm> using namespace std; #define maxn 6010int fa[maxn],dp[maxn][2]; int root,n; int v[maxn]; int nxt[maxn],head[maxn];void treedp(int x){for(int i = head[x];i;i = nxt[i]){treedp(i);dp[x][0] += max(dp[i][1],dp[i][0]);//dp[x][0]代表上司x不来时的最大快乐指数dp[x][1] += dp[i][0];//dp[x][1]代表上司来的 } }int main() {scanf("%d",&n);for(int i = 1; i <= n; i++)scanf("%d",&dp[i][1]);for(int i = 1; i < n; i++) {int x,y;scanf("%d%d",&x,&y);v[x] ++;//记录一下有没有上司nxt[x] = head[y];head[y] = x;//对,像链式前向星的东西(我还理解了好久【划掉 }for(int i = 1; i <= n; i++)if(!v[i]) {//没有上司的就是最大上司啦root = i;break;}treedp(root);//从树根开始dpprintf("%d",max(dp[root][0],dp[root][1]));//取最高上司来和不来的最大快乐指数return 0; }
emmmmm
还是蛮好懂的吧
然后上下一道
传送门 ———>luogu P1122 最大子树和
这里有一点点的变化
就是剪掉了之后是加0
#include<cstdio> #include<algorithm> using namespace std; #define maxn 16010int dp[maxn]; int cnt,head[maxn * 2]; int f[maxn];//记录当前子节点到之下的花的最大值 int ans = -2147483647;//因为可能全是负的所以ans搞到最小struct EDGE{int nxt,to; }edge[maxn * 2];void add(int x,int y){edge[++cnt].to = y;edge[cnt].nxt = head[x];head[x] = cnt; }//正常的加边看上去真舒服啊void treedp(int u,int fa){f[u] = dp[u];//给f[u]赋值为它本身的大小for(int i = head[u];i;i = edge[i].nxt){int v = edge[i].to;//v是u的儿子if(v != fa){//唔防止双向加边跑回去 treedp(v,u);f[u] += max(0,f[v]);}}ans = max(ans,f[u]);//反正所有的花都在一根上不需要加和什么的(我在说什么废话 }int main(){int n;scanf("%d",&n);for(int i = 1;i <= n;i++)scanf("%d",&dp[i]);for(int i = 1;i < n;i++){int x,y;scanf("%d%d",&x,&y);add(x,y);add(y,x);}treedp(1,0);//将1的父节点定义为0printf("%d",ans);return 0; }
唔嗷【好困
(明天的联欢是我写博客的动力【不小心暴露了什么
下一道来
传送门———>luogu P2016 战略游戏
(吓死我了插链接的时候突然闪退了(╥﹏╥)还好有自动保存这种可爱的东西
emmmm
这道题似乎又回到了原点?
其实跟没有上司的舞会很像
就是上司不来,下属必须来
上司来,下属来不来都行
(有点像开会?总得来一个负责人,当然都希望来的越少越好了【因为懒
#include<cstdio> #include<algorithm> using namespace std; #define maxn 1510struct EDGE{int nxt,to; }edge[maxn];int cnt,head[maxn]; int v[maxn]; int dp[maxn][2];void add(int x,int y){edge[++cnt].to = y;edge[cnt].nxt = head[x];head[x] = cnt; }void treedp(int x){dp[x][1] = 1;//放的地方都是一for(int i = head[x];i;i = edge[i].nxt){int u = edge[i].to;treedp(u);dp[x][0] += dp[u][1];//当前点不放,下一个点一定要放dp[x][1] += min(dp[u][1],dp[u][0]);当前放了下一个点不一定放不放} }int main(){int n;scanf("%d",&n);for(int i = 0;i < n;i++){int r,k;scanf("%d%d",&r,&k);for(int j = 0;j < k;j++){int p;scanf("%d",&p);v[p]++;add(r,p);}}int root;for(int i = 0;i < n;i++)if(!v[i]){root = i;break;}//唔又是找根 treedp(root);printf("%d",min(dp[root][0],dp[root][1]));return 0; }
啊友情提示
a掉这道题之后可以顺道a掉luogu UVA1292 Strategic game
差别就是这道题要输入多组数据而已
/*
emmmmm
去写选课
写完就发
*/
好的我鸽了
告辞【快速溜
转载于:https://www.cnblogs.com/sevenyuanluo/p/10192869.html
树形dp瞎讲+树形dp基础题题解相关推荐
- 51nod 基础题题解(全)
基础题(40): 1000 A + B 1005 大数加法 1006 最长公共子序列Lcs 1018 排序 1019 逆序数 1027 大数乘法 1046 A^B Mod C 1057 N的阶乘(大数 ...
- ZOJ 3527 树形DP(章鱼图DP)
题意 有N个村庄,每个村庄有一定的信仰值,占领村庄可以得到信仰值,每个村庄有一个关联村庄,同时占领关联村庄可以得到加成(可能为负),问占领一些村庄,最多可以得到多少信仰值 题解 这个DP已经不能算是树 ...
- 【AcWing】数位统计DP、树形DP、状态压缩DP、记忆化搜索
[AcWing]数位统计DP.树形DP.状态压缩DP.记忆化搜索 一.数位统计DP 二.状态压缩DP 三.树形DP 四.记忆化搜索 一.数位统计DP 计数问题 给定两个整数 a 和 b,求 a 和 b ...
- [DP魔炼][DP] DP随练随学(疯狂A题训练——DP基础篇 题解 下)
终于写完啦!!!!!!!! T28 最大子段和 传送门 维护前缀和 找前面最小的 #include<bits/stdc++.h> using namespace std; #define ...
- 牛客假日团队赛5 K 金币馅饼 (DP 基础题)
链接:https://ac.nowcoder.com/acm/contest/984/K 来源:牛客网 金币馅饼 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...
- A. Boredom(线性dp基础题)
题目的大意是:给定你一个数组,每次可以删掉一个大小为a的数,获得a的分数,同时删除数列中所有大小为a+1和a-1的数.问删除所有数组中的数后,能够获得的最大分数值. 思路:本题可以用线性dp来解决.d ...
- 寒假每日一题题解(1.29)摘花生(DP水题)
摘花生 Hello Kitty想摘点花生送给她喜欢的米老鼠. 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来. 地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过 ...
- 刷题周记(九)——#状压DP:最短Hamilton路径、小国王(互不侵犯)、玉米田(Corn Fields G)、愤怒的小鸟、吃奶酪、炮兵阵地、宝藏 #区间DP:清空字符串#DP:关灯问题II
文章目录 --2020年12月20日(周日)------------------ 状压DP 一.最短Hamilton路径(模板题) 二.玉米田(P1879 [USACO06NOV]Corn Field ...
- c语言dp算法,C++动态规划dp算法题
问题1:找硬币,换钱的方法 输入: penny数组代表所有货币的面值,正数不重复 aim小于等于1000,代表要找的钱 输出: 换钱的方法总数 解法1:经典dp,空间复杂度O(n*aim) class ...
最新文章
- 动态树与静态树显示——(一)
- STM32F103+UCOS-II 实现临界区不关闭重要中断
- 今晚直播 | 北邮博士生纪厚业:异质图神经网络之模型和应用
- Leet Code OJ 168. Excel Sheet Column Title [Difficulty: Easy]
- 口袋操作系统_全自动阀口袋包装机的发展
- 如何从零搭建一个hexo博客网站02
- freeswitch 文件包含关系图
- 抖音直播视频下载保存到本地地瓜网络技术
- android nexus 刷机工具包,Nexus5刷机救砖Recovery详细教程
- LaTex - 插入公式 (从MathType公式编辑器导入到LaTex中)
- 服务器的硬盘分盘,服务器硬盘分区教程
- 从零开始用人工智能预测股票(二、数据加工)
- 007数据分析能力:业务题
- python 借助opencv实现Gabor滤波特征提取
- 【ZZULIOJ】1008: 美元和人民币
- eCognition9.0安装教程
- tf.cancat() 详解 —》理解为主
- java创建多个线程 延时1秒_Java 多线程(三)优化任务执行
- 【opencv】 使用at和ptr指针访问像素的区别
- 新品周刊 | 昕诺飞发布飞利浦智能照明产品;AO史密斯推出新品空气净化器