题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520
题目解释:给定一些人的开心指数,要求开心指数总数和最大,只有当这个的上司不在时才能获得开心指数
方法:动态规划+dfs,先找到没有上司的人,每个有可以被选也可以不被选,判断被选和不被选的最大值,逐级累加,被选时下属一定不会开心,不被选时下属可以被选也可以不被选
代码:
#include<iostream>
#include <cstdio>
#include <cstring>
#include<vector>
#include <algorithm>
using namespace std;
int a[6005],dp[6005][2],vis[6005],father[6005];
vector<int> son[6005];
void dfs(int root)
{
vis[root]=1;
dp[root][1]=a[root];
for(int i=0;i<son[root].size();i++)
{
int l=son[root][i];
//cout<<root<<" "<<l<<endl;
if(!vis[l]){
dfs(l);
dp[root][0]+=max(dp[l][0],dp[l][1]);//不出席的开心指数
dp[root][1]+=dp[l][0];//出席的开心指数
}
}
}
int main()
{
int n;
int l,k;
int root;
while(scanf("%d",&n)!=EOF&&n){
for(int i=1; i<=n; ++i) son[i].clear();
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(father,0,sizeof(father));
while((scanf("%d %d",&l,&k))&&l&&k)
{
son[k].push_back(l);
father[l]++;
// cout<<root<<endl;
}
memset(dp,0,sizeof(dp));
//cout<<root<<endl;
for(int i=1;i<=n;i++)
{
if(father[i]==0)
{
memset(vis,0,sizeof(vis));
root=i;
dfs(root);
break;
}
}
printf("%d\n",max(dp[root][0],dp[root][1]));}
return 0;
}

本文介绍了一道经典的动态规划问题——如何在考虑上下级关系的前提下最大化团队的开心指数。通过DFS遍历寻找没有上司的员工开始,采用动态规划策略递归地计算出每个员工出席或缺席时的最优解。
691

被折叠的 条评论
为什么被折叠?



