聚会的快乐
题目描述 你要组织一个由你公司的人参加的聚会。你希望聚会非常愉快,尽可能多地找些有趣的热闹。但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵。给定N个人(姓名,他幽默的系数,以及他上司的名字),编程找到能使幽默系数和最大的若干个人。 输入输出格式 输入格式: 第一行一个整数N(N<100)。接下来有N行,每一行描述一个人的信息,信息之间用空格隔开。姓名是长度不超过20的字符串,幽默系数是在0到100之间的整数。 输出格式: 所邀请的人最大的幽默系数和。 输入输出样例 输入样例#1: 5 BART 1 HOMER HOMER 2 MONTGOMERY MONTGOMERY 1 NOBODY LISA 3 HOMER SMITHERS 4 MONTGOMERY 输出样例#1: 8
明显的树形DP
dp[i][0] 表示i这个点不选的最大值
dp[i][1] 表示i这个点选的最大值
转移:
如果i这个点选择,那么他的直系下属就不可以参加,
dp[i][0]+=dfs(to,0);
如果i这个点不选择选择,那么他的直系下属就可以参加也可以不参加
dp[i][1]+=max(dfs(to,0),dfs(to,1));
记忆化搜索,转移
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define DB double 4 using namespace std; 5 int n,dp[110][2],val[110],son[110],t[110][110],rt,ans; 6 bool vis[110][110]; 7 string na[110],up[110]; 8 int dfs(int i,int j) 9 { 10 if(vis[i][j]) return dp[i][j]; 11 vis[i][j]=true; 12 if(i==0) return 0; 13 if(j==1)//这个人参加聚会 14 { 15 dp[i][j]=val[i]; 16 for(int k=1;k<=son[i];++k) dp[i][j]+=dfs(t[i][k],0); 17 } 18 else//人不参加聚会 19 { 20 for(int k=1;k<=son[i];++k) 21 dp[i][j]+=max(dfs(t[i][k],0),dfs(t[i][k],1)); 22 } 23 return dp[i][j]; 24 } 25 int main() 26 { 27 scanf("%d",&n); 28 for(int i=1;i<=n;++i) 29 cin>>na[i]>>val[i]>>up[i]; 30 for(int i=1;i<=n;++i) 31 { 32 bool fg=false; 33 for(int j=1;j<=n;++j) 34 { 35 if(i==j)continue; 36 if(na[j]==up[i]) 37 { 38 fg=true; 39 t[j][++son[j]]=i; 40 break; 41 } 42 } 43 if(!fg) rt=i; 44 } 45 ans=dfs(rt,0); 46 ans=max(ans,dfs(rt,1)); 47 printf("%d\n",ans); 48 return 0; 49 }