这是一道树形dp题,dp[i][0]代表这个职员不来,dp[i][1]代表这个职员来。当这个职员要来的话,他的所有直接下属都是不会来的,当这个职员不来的话,他的所有直接下属可以来也可以不来。我们就可以写出状态转移方程式dp[u][1] = Σdp[v][0],dp[u][0] = Σmax(dp[v][0],dp[v][1])。其中 u 代表当前节点, v 表示子节点。
#include
using namespace std;
int a[6005];
vector< int >road[6005];
int dp[6005][2];
int dfs( int u, int flag)
{
if (dp[u][flag])
{
return dp[u][flag];
} //记忆化
if (flag)
{
dp[u][flag] = a[u];
for ( int i = 0;i < road[u].size();i++)
{
int v = road[u][i];
dp[u][flag] += dfs(v,!flag);
}
//当前节点来
}
else
{
for ( int i = 0;i < road[u].size();i++)
{
int v = road[u][i];
dp[u][flag] += max(dfs(v,flag),dfs(v,!flag));
}
//当前节点不来
}
return dp[u][flag];
}
bool flag[6005];
int main(){
int n;
cin >> n;
for ( int i = 1;i <= n;i++)
{
cin >> a[i]; //来后的开心值
}
for ( int i = 1;i < n;i++)
{
int x,y;
cin >> x >> y;
road[y].push_back(x); //x是y的直接下属
flag[x] = true ;
}
int id = 0;
for ( int i = 1;i <= n;i++)
{
if (!flag[i])
{
id = i;
break ;
}
} //找最大的老板
cout << max(dfs(id,0),dfs(id,1)); //最大的老板来或不来取最大值
return 0;
}
浙公网安备 33010602011771号