洛谷P2014 选课
来源:互联网 发布:好吃的月饼 知乎 编辑:程序博客网 时间:2024/06/16 00:40
题目来源:https://www.luogu.org/problem/show?pid=2014#sub
树形dp。关键是存树的方式。
在森林上找多个包含树根的连通块,使所有点的权值最大。
用二叉树存储,定义两个数组head和next,其中head[i]表示节点i的第一个儿子节点,next[i]表示节点i的兄弟节点。
若以知一个节点的父亲,则插入该节点的代码:
if(head[fa]==0)head[fa]=i;else{ int t=head[fa]; while(next[t]!=0)t=next[t]; next[t]=i;}
dp方程:
f[c][s]表示在二叉树中以c为根的子树中取s个节点的最大权值,其中这s个节点均联通。
f[c][s]=a[c]+max(f[head[c]][i],f[next[c]][s-1-i]);
由于二叉树中节点c的右节点实际上与c是兄弟关系,故f[c][s]的值可以不包含节点c,故还应保证
f[c][s]=max(f[c][s],f[next[c]][s]);
代码:
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <sstream>#include <cstdio>#include <string>#include <vector>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <set>#include <map>using namespace std;int a[1001];int head[1001],next[1001];int f[1001][1001];int dp(int c,int s){ if(s==0)return 0; if(c==0)return 0; if(f[c][s]!=0)return f[c][s]; for(int i=0;i<s;i++)f[c][s]=max(f[c][s],a[c]+dp(head[c],i)+dp(next[c],s-1-i)); f[c][s]=max(f[c][s],dp(next[c],s)); return f[c][s];}int main(){ ios::sync_with_stdio(false); int n,m;cin>>n>>m; for(int i=1;i<=n;i++) { int fa;cin>>fa; if(head[fa]==0)head[fa]=i; else { int t=head[fa]; while(next[t]!=0)t=next[t]; next[t]=i; } cin>>a[i]; } cout<<dp(head[0],m); return 0;}
0 0
- 洛谷 P2014 选课
- 洛谷P2014 选课
- [洛谷p2014]选课
- 洛谷P2014 选课
- 洛谷P2014 选课
- 洛谷 P2014 选课
- 洛谷P2014 选课
- 洛谷 P2014 选课
- |洛谷|动态规划|P2014 选课
- 树形dp-洛谷 P2014 选课
- 树形DP 洛谷P2014 选课
- (洛谷P2014 选课)<树形DP>
- 洛谷 p2014 [CTSC2001] 选课 树形背包DP
- luogu P2014 选课 树形背包
- [题解] P2014 选课(树形DP+拓扑)
- 【洛谷2014】选课
- 洛谷 2014 选课
- 洛谷2014选课
- 散列表的C程序实现,基于数组实现可以实现增删改查操作,
- 谈谈最近的阅读体验
- 安卓事件分发机制简解
- MYSQL免安装版配置
- 读书进度
- 洛谷P2014 选课
- 如何起草你的第一篇科研论文——应该做&避免做
- View的事件分发机制
- matlab基本知识(入门)
- webkit高级浏览器li居中方法
- Android温习之路:day9java基础9
- android studio代码混淆
- Spark在Windows下的环境搭建
- CSAPP(深入理解计算机系统)