poj2342—树形dp
2015-09-15 16:06
399 查看
华电北风吹
天津大学认知计算与应用重点实验室
日期:2015/9/15
poj上一道与动态规划特别像的题目(http://poj.org/problem?id=2342),一个公司要出席一些人员,每个人对应一个活跃度,要求是不能存在直属关系,活跃度最大。参考了别人的博客,很多人说这个是树形动态规划,我个人感觉应该划分到分治法里面(不存在重叠子问题)。
下面是我修改后的代码,采用递归的思路。例如计算根节点的最大活跃度,需要判断根节点的每一个子节点,根节点出席的话就把子节点不出席时候的活跃度相加,如果根节点不出席,就把所有根节点出席和不出席中活跃度最大的加起来,依次递归。其中,leader保存每个节点的直属leader,dp[i][0/1] 保存当前节点子树出席和不出席的活跃度。
C++ code:
python code:
天津大学认知计算与应用重点实验室
日期:2015/9/15
poj上一道与动态规划特别像的题目(http://poj.org/problem?id=2342),一个公司要出席一些人员,每个人对应一个活跃度,要求是不能存在直属关系,活跃度最大。参考了别人的博客,很多人说这个是树形动态规划,我个人感觉应该划分到分治法里面(不存在重叠子问题)。
下面是我修改后的代码,采用递归的思路。例如计算根节点的最大活跃度,需要判断根节点的每一个子节点,根节点出席的话就把子节点不出席时候的活跃度相加,如果根节点不出席,就把所有根节点出席和不出席中活跃度最大的加起来,依次递归。其中,leader保存每个节点的直属leader,dp[i][0/1] 保存当前节点子树出席和不出席的活跃度。
C++ code:
#include<iostream> #include<fstream> #include<algorithm> using namespace std; #define maxn 100 int n; int dp[maxn][2], leader[maxn]; //dp[i][0]0表示不去,dp[i][1]1表示去了 void tree_dp(int node) { int i; for (i = 1; i <= n; i++) { if (leader[i] == node) //i为下属 { tree_dp(i); //递归调用孩子结点,从叶子结点开始dp dp[node][1] += dp[i][0]; //上司来,下属不来 dp[node][0] += max(dp[i][1], dp[i][0]); //上司不来,下属来、不来 } } } int main() { ifstream in("C:\\Users\\zhengyi\\Desktop\\ConsoleApplication1\\input.txt"); cin.rdbuf(in.rdbuf()); int i; int f, c, root; while (cin>>n) { memset(dp, 0, sizeof(dp)); memset(leader, 0, sizeof(leader)); for (i = 1; i <= n; i++) { cin>>dp[i][1]; } while (cin>>c>>f, c || f) { leader[c] = f; root = f; } while (leader[root]) //查找父结点 root = leader[root]; tree_dp(root); int imax = max(dp[root][0], dp[root][1]); printf("%d\n", imax); } system("pause"); return 0; }
python code:
file=open('datahdu1520.txt','r') line=file.readline() N=int(line.strip('\n')) activity=[int(file.readline().strip('\n')) for i in range(N)] leader=[i for i in range(N)] root=0 while True: line=file.readline() if line=="0 0": break line=line.split() leader[int(line[0])-1]=int(line[1])-1 root=int(line[1])-1 dp=[[0 for col in range(2)] for row in range(N)] def func(person): dp[person][0]=0 dp[person][1]=activity[person] for i in range(N): if leader[i]==person and i!=person: func(i) dp[person][0]=dp[person][0]+max(dp[i]) dp[person][1]=dp[person][1]+dp[i][0] while leader[root]!=root: root=leader[root] func(root) print(max(dp[root]))
相关文章推荐
- ActiveMQ与RabbitMQ采用camel综合
- 使用Inno Setup打包Winform程序
- UVALive 5906 Smoking gun(差分约束 + toposort)
- docker 数据管理
- unity3d动画插件iTween
- android 录像和拍照功能
- 【Linux】linux常用基本命令
- awk引用shell中变量的几种方法
- React 生命周期 笔记
- os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
- 从服务器中返回的时间字符串(或时间戳)的一些简单处理
- os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
- XMLHttpRequest cannot load – Origin is not allowed by Access-Control-Allow-Origin.
- 在 Android 使用 C# 开发 iBeacons 应用
- Android - 优化WebView页面
- 算法
- 我所了解到的分布式技术
- HDOJ-3037(组合数学)
- java通过一个url读取网站的源代码 储存到本地文件中
- 【Leet Code】 242. Valid Anagram--easy