HDU 1520 Anniversary party(树形DP)

本文介绍了一个关于树形动态规划的入门级算法,详细解释了如何通过递归实现从叶子节点到根节点的DP过程,最终输出根节点的最大rank。

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520


这个应该算是树形DP入门级的题目了,比较简单,每个节点设置两个值,一个是my是选择自己时的rank值最大,一个是other

表示不选择自己时的rank最大,然后从叶子节点开始DP(从根递归实现),最后输出根节点my 和 other中较大的一个


#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
#define maxn 10000
#define MAX(a,b) (a>b?a:b)
struct node{
    int rank;
    int my,other;
    vector<int> child;
}po[maxn];
int n;
bool is_root[maxn];
int tree_dp(int root){
    if(po[root].child.empty()){
        po[root].my=po[root].rank;
        po[root].other=0;
        return 0;
    }
    for(int i=0;i<po[root].child.size();i++){
        tree_dp(po[root].child[i]);
    }
    int ans1=0,ans2=0;
    for(int i=0;i<po[root].child.size();i++){
        ans1+=MAX(po[po[root].child[i]].my,po[po[root].child[i]].other);
        ans2+=po[po[root].child[i]].other;
    }
    po[root].my=ans2+po[root].rank;//表示选自己就一定不能选其子节点的任意一个,所以所有子节点都要选other
    po[root].other=ans1;//表示不选自己
    return 0;
}
int main(){
    int i,j,k,a,b,root;
    while(scanf("%d",&n)!=EOF){
        for(i=1;i<=n;i++){
            scanf("%d",&po[i].rank);
            po[i].my=po[i].other=0;
            po[i].child.clear();
        }
        memset(is_root,true,sizeof(is_root));
        while(scanf("%d%d",&a,&b),a+b){
            po[b].child.push_back(a);
            is_root[a]=false;
        }
        for(i=1;i<=n;i++)
        if(is_root[i]){
            root=i; break;
        }
        tree_dp(root);
        printf("%d\n",MAX(po[root].my,po[root].other));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值