没有上司的舞会(树形dp)
题目链接: https://www.luogu.com.cn/problem/P1352
题意:
给定一棵职员树,父节点为子节点的直接上司,每个员工有其快乐值。
每个员工不会与其直接上司同时参加舞会
求该场舞会邀请人员的最大快乐值
思路:
树形dp
定义状态:dp[i][0]表示不选第i个人,邀请到子节点人及其自己的最大快乐值
dp[i][1]表示选第i个人,邀请到子节点人及其自己的最大快乐值
状态转移:发现不选第i个人,其直接儿子便可以选上,所以dp[i][0]=max(dp[son][0],dp[son][1])
选第i个人,无法选上其直接儿子,所以dp[i][1]=dp[son][0]
初始化:每个dp[i][1]=ri(每个人自身的快乐值)
dp[i][0]=0
具体实现:
从小推到大,所以从根节点dfs
在返回的途中计算dp值
最后答案便是max(dp[root][0],dp[root][1])
#include<bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<=n;i++) #define pb push_back #define endl "\n" #define fi first #define se second //#pragma GCC optimize(3) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const int inf=0x3f3f3f3f; const ll llmax=LLONG_MAX; const int maxn=1e5+5; const int mod=1e9+7; int n; int r[maxn]; vector<int>e[6005]; int a[maxn]; int dp[6005][2]; void dfs(int x){ dp[x][1]=r[x]; for(auto ed:e[x]){ dfs(ed); dp[x][0]+=max(dp[ed][1],dp[ed][0]); dp[x][1]+=dp[ed][0]; } } signed main() { ios::sync_with_stdio(false),cin.tie(0); cin>>n; rep(i,1,n)cin>>r[i]; rep(i,1,n-1){ int l,k;cin>>l>>k; e[k].pb(l); a[l]=k; } int tp; rep(i,1,n){ if(a[i]==0){ tp=i; } } dfs(tp); cout<<max(dp[tp][0],dp[tp][1]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现