POJ - 2342 Anniversary party 树形DP

博客介绍了POJ 2342问题的解决方案,即如何在避免邀请员工及其直属上司的前提下,最大化年会的欢乐值。解题策略涉及树形动态规划,通过维护dp[i][1](邀请第i人)和dp[i][0](不邀请第i人)的状态来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:公司要开年会,要邀请员工,每个员工都有其对应的欢乐值。现要求在员工何其直属上司不能同时邀请的情况下,使得欢乐值最大

解题思路:设dp[i][1]表示邀请第i个人的情况,dp[i][0]表示没有邀请第i个人
那么dp[i][j] += sum(dp[j][0])
dp[i][0] = sum( max(dp[j][0],dp[j][1]))
dp[i][1]初始化为happy[i],dp[i][0]初始化为0,这样就可以做了

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 6010
vector<int> tree[maxn];
int N, happy[maxn], dp[maxn][2], vis[maxn];

void init() {

    for(int i = 1; i <= N; i++) {
        scanf("%d", &happy[i]);
        vis[i] = 0;
        tree[i].clear();
    }

    int L, K;
    while(scanf("%d%d", &L, &K) != EOF && L + K) {
        tree[K].push_back(L);
        vis[L] = 1;
    }

    tree[0].clear();
    for(int i = 1; i <= N; i++)
        if(!vis[i])
            tree[0].push_back(i);
}

void dfs(int cur) {
    dp[cur][1] = happy[cur];
    dp[cur][0] = 0;

    for(int i = 0; i < tree[cur].size(); i++) {
        dfs(tree[cur][i]);
        dp[cur][1] += dp[tree[cur][i]][0];
        dp[cur][0] += max(dp[tree[cur][i]][0], dp[tree[cur][0]][1]);
    }
}

void solve() {
    int ans = 0;
    for(int i = 0; i < tree[0].size(); i++) {
        dfs(tree[0][i]);
        ans += max(dp[tree[0][i]][0], dp[tree[0][i]][1]);
    }

    printf("%d\n", ans);
}

int main() {
    while(scanf("%d", &N) != EOF) {
        init();
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值