这周是计划学习树形dp的,但是因为复习其他的事情耽误了点计划,后面又突然出了事就急忙收拾行李改了车票,到今天凌晨才刚到家
树形dp首先是一些比较简单的题目就像上次提到的poj 2342 Anniversary party,根据不同情况分为不同节点,由节分分成不同的叶,如
- dp[node][1] += dp[i][0];//上司来,下属不来
- dp[node][0] +=max(dp[i][1],dp[i][0]);//上司不来,下属来、不来
这种是比较简单的分情况,
也还有其他的比较难的本来树的内容就有很多,像是什么二叉树,树的遍历什么都可以结合动规进行
- #include
-
- using namespace std;
-
- const int ee=105;
- int n,q;
- int tree[ee][5]={0},ma[ee][ee]={0},num[ee]={0},f[ee][ee]={0};
-
- void preproccess()
- {
- for(int i=0;i<=n;i++)
- for(int j=0;j<=n;j++)
- {
- ma[i][j]=-1;
- ma[j][i]=-1;
- }
- }
-
- void maketree(int v);
-
- void build(int x,int y,int lor)//lor means left or right
- {
- num[y]=ma[x][y];
- tree[x][lor]=y;
- ma[x][y]=-1;ma[y][x]=-1;
- maketree(y);
- }
-
- void maketree(int v)
- {
- int lr=0;
- for(int i=0;i<=n;i++)
- if(ma[v][i]>=0)//如果分叉了,那么记录
- {
- lr++; //1 or 2 表示左支还是右支;
- build(v,i,lr);//存入并递归
- if(lr==2) return;
- }
- }
-
- void dfs(int v,int k)
- {
- if(k==0) f[v][k]=0;
- else if(tree[v][1]==0 && tree[v][2]==0) f[v][k]=num[v];
- else
- {
- f[v][k]=0;
- for(int i=0;i
- {
- if(f[tree[v][1]][i]==0) dfs(tree[v][1],i);
- if(f[tree[v][2]][k-i-1]==0) dfs(tree[v][2],k-i-1);
- f[v][k]=max(f[v][k],(f[tree[v][1]][i]+f[tree[v][2]][k-i-1]+num[v]));
- }
- }
- }
-
- int main()
- {
- cin>>n>>q;
- preproccess();
-
- for(int i=0;i
- {
- int x,y,xy;
- scanf("%d%d%d",&x,&y,&xy);
- ma[x][y]=xy;
- ma[y][x]=xy;
- }
-
- //建树;
- maketree(1);
- dfs(1,q+1);
- cout<
1][q+1]; - return 0;
- }
关于树dp 还有很多类型,没有了解,下周还是练习树形dp的题目
-
相关阅读:
MySQL中 any,some,all 的用法
百度翻译很方便,几点注意事项
嵌入式学习笔记(63)位操作实战
[UUCTF 2022 新生赛]ezpop - 反序列化+字符串逃逸【***】
使用安卓Termux+Hexo,手机也能轻松搭建个人博客网站
大数据架构系列:如何理解湖仓一体?
(STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(2)
LeetCode八月每日一题题解(个人记录打卡)
深入理解MySQL:数据类型、查询优化、索引、事务处理和数据备份与恢复
智能微型断路器应该怎么选型?
-
原文地址:https://blog.csdn.net/weixin_60840655/article/details/128192584