Anniversary party

本文深入探讨了树形动态规划的基本概念与算法实现,通过一个具体的员工快乐值问题,详细解析了如何利用树形DP解决最优化问题,展示了递归函数的编写技巧,并提供了完整的代码示例。

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

Anniversary party

树形dp

dp[i][0]=(i的全部员工的max(dp[u][1],dp[u][0)相加,也就是其子员工来或不来的最大快乐值。

dp[i][1]=(i的全部员工的dp[u][0相加,也就是其子员工都不能不来的最大快乐值。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;
typedef long long LL;
#define mst(s, t) memset(s, t, sizeof(s))
const int INF = 0x3f3f3f3f;
const int maxn = 10010;
vector<int> G[maxn];
int A[maxn];
int dp[maxn][2];
int n;
void dfs(int node, int father)
{
    //若是叶子结点则return sum=1,否则求其子树(包括自己)的总结点数
    dp[node][0]=0;
    dp[node][1]=A[node];
    for(int i=0; i<G[node].size(); i++)
    {
        if(G[node][i] == father)continue; //因为是树结构,这里可以在无向时避免遍历成环
        dfs(G[node][i],node);
        dp[node][0]+=max(dp[G[node][i]][0], dp[G[node][i]][1]);
        dp[node][1]+=dp[G[node][i]][0];
    }
    return ;
}


signed main()
{
    //freopen("in.txt", "r", stdin);
    scanf("%I64d", &n);
    for(int i=1; i<=n; i++)
    {
        scanf("%I64d",&A[i]);
    }

    int a,b;
    while(scanf("%I64d%I64d", &a, &b))

    {
        if(a==b&&a==0)break;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    dfs(1, 0);
    cout<<max(dp[1][0],dp[1][1])<<'\n';
    //cout << n << "==" << tmp << endl; //验证
    return 0;
}

 

转载于:https://www.cnblogs.com/liulex/p/11394550.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值