解题报告 『没有上司的舞会(树形动规)』

本文深入解析树状动态规划(DP)的核心概念与状态转移方程,通过具体实例演示如何选择节点进行优化,适用于初学者掌握DP技巧。文章详细介绍了两组关键状态方程,dp[u][0]和dp[u][1],并提供了代码实现,帮助读者理解根节点确定与DP递归调用过程。

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

原题地址

很经典的一道树状DP题,很适合新手(比如我这种)用来学习或练手,首先推出状态转移方程,然后……

就没有然后了。

 

选择节点类方程:

dp[u][0] = sum(max(dp[v][1], dp[v][0]));(v是u的儿子)

你不去,那下属可以去或不去。

dp[u][1] = sum(dp[v][0]) + happy[u];(v是u的儿子)

你去了,那下属就一定不会去。

代码实现如下:

void dp(int u) {
    f[u][0] = 0;
    f[u][1] = happy[u];
    rep(i, 0, son[u].size() - 1) {
        int v = son[u][i];
        dp(v);
        f[u][0] += max(f[v][0], f[v][1]);
        f[u][1] += f[v][0];
    }
}
View Code

 

不过在这之前需要先找到根结点root,可以用一个bool数组。每读入一个结点x,如果其有上司,则bool[x]赋值为1,然后for循环,bool值为0的即为根结点root。

代码实现如下:

rep(i, 0, n - 2) {
        int u, v;
        u = read();
        v = read();
        son[v].push_back(u);
        vis[u] = 1;
    }
    rep(i, 0, n - 1)
    if (!vis[i]) {
        root = i;
        break;
    }
    dp(root);
View Code

转载于:https://www.cnblogs.com/Kirisame-Marisa/p/10292259.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值