poj2342/poj3342——基础的树形DP
来源:互联网 发布:网络优化工程师面试题 编辑:程序博客网 时间:2024/04/28 16:01
poj2342:
题目大意:
大学要开年会,请公司的人来参加聚会,但是不希望员工和其最直接的上司同时出现在聚会上,问最多能邀请到多少人参加聚会。
解题思路:
转化成树的结构就是父亲节点和孩子节点不能同时出现。
设dp[i][0] 表示不取第i个人能得到的最大人数。
dp[i][1] 表示取第i个人能得到的最大人数。
可以得到如下的状态转移方程:
dp[i][0]+=max(dp[j][0],dp[j][1])
dp[i][1]+=dp[j][0]
其中j是i的孩子节点。
所以我们只需要对根节点进行一次dfs求出所有的dp数组所有的值。
最后结果就是 max(dp[root][1] ,dp[root][0])
poj3342是上题的升级版本,除了求出最多人数之外,还需要判断最多人数的方案是否唯一。
方案唯一性的判断方法:
第1:如果dp[root][1]==dp[root][0],则方案必不唯一。
第2:如果dp[i][1]==dp[i][0],并且dp[father][0]>=dp[father][1]。
如果存在某节点其取与不取最大值是一样的,并且其父节点在不取的时候得到最大人数。
那么,这个时候方案不唯一。
poj3342源代码:
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<set>#include<map>#include<vector>#include<algorithm>#include<iostream>#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;const double eps=1e-8;int n;int dp[205][2];int flag;struct node{ int father; vector<int> child;}p[205];int vis[205];void dfs(int now){ int flag1; int i,size,child; vis[now]=1; size=p[now].child.size(); flag1=0; for(i=0;i<size;i++) { child=p[now].child[i]; if(!vis[child]) { dfs(child); dp[now][0]+=max(dp[child][0],dp[child][1]); dp[now][1]+=dp[child][0]; } } return;}int main(){freopen("in.txt","r",stdin);int i,x,y,cnt,j;char ch[105];string a,b;while(scanf("%d",&n)==1 && n){ map<string,int> m; memset(p,0,sizeof(p)); cin>>a; m[a]=1; cnt=1; for(i=1;i<n;i++) { cin>>a>>b; x=m[a],y=m[b]; if(m[a]==0) { m[a]=++cnt; x=cnt; } if(m[b]==0) { m[b]=++cnt; y=cnt; } //x和y已经是映射好的值了,x是y的下属 p[y].child.push_back(x); p[x].father=y; } memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) dp[i][1]=1; memset(vis,0,sizeof(vis)); dfs(1); printf("%d ",max(dp[1][1],dp[1][0])); //唯一性的判断,当前节点取和不取结果是一样的, //并且其父亲节点不取,这样的话必然出现多种可能的选择 flag=1; if(dp[1][1]==dp[1][0]) flag=0; for(i=2;i<=n;i++) { if(dp[i][1]==dp[i][0] && dp[p[i].father][0]>=dp[p[i].father][1]) { flag=0; break; } } if(flag) printf("Yes\n"); //是独一无二的 else printf("No\n"); //不是独一无二的 m.clear(); //用完之后将m清空}return 0;}
- poj2342/poj3342——基础的树形DP
- poj3342 poj2342 树形dp入门
- poj2342—树形dp
- poj3342树形dp
- poj2342——Anniversary party(树形dp)
- poj2342 简单树形DP
- poj2342 树形dp
- POJ2342 简单树形dp
- poj2342树形dp
- 树形dp poj2342
- poj2342&&hdu1520(树形dp)
- poj2342 树形dp入门
- POJ2342(树形dp)
- poj2342(树形dp)
- POJ2342:Anniversary party(树形DP)
- poj2342 Anniversary party【树形dp】
- POJ2342 Anniversary party(树形DP)
- poj2342.Anniversary party(树形dp)
- 浏览器探究——APP层UI布局
- ACM - 第七,八天:mark今日,打酱油过
- oracle alter table详解
- Maven学习一:用Maven创建Java Project
- HDU 2001 计算两点间的距离
- poj2342/poj3342——基础的树形DP
- Html和asp.net中本地根目录的区别
- SQL中的集合运算符
- cocos2d-x学习之路(15)--CCTaleView的使用
- 总结在Hibernate学习中出现的错误
- Eclipse插件第三方库导出问题分析
- 【Java学习笔记】基础知识学习8【字符串比较】
- HTML5 绘制简单的飞机模型
- Eclipse中使用自己的makefile管理工程