Acwing 0x50 动态规划~没有上司的舞会

探讨了在Ural大学中如何邀请职员参加宴会的问题,旨在最大化参会职员的快乐指数总和,同时确保没有职员与直接上司一同参会。通过动态规划算法解决此问题,详细解释了算法思路及代码实现。

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

题目链接:https://www.acwing.com/problem/content/287/

题意

Ural大学有N名职员,编号为1-N

他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。

每个职员有一个快乐指数,用整数Hi 给出,其中 1\leq i\leqslant N

现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。

在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入格式

第一行一个整数N

接下来N行,第i行表示i 号职员的快乐指数Hi 。

接下来N-1行,每行输入一对整数L, K,表示KL的直接上司。

最后一行输入0,0。

输出格式

输出最大的快乐指数。

数据范围

1\leq N\leq 6000,
-128\leq Hi\leq 127

题解

f[x][0]表示从以x为根的子树邀请一部分职员参会,并且x不参加舞会时,快乐指数总和的最大值。此时,x的所有子节点(直接下属)可以参会,也可以不参会。

f[x][0]=\sum\limits_{s\epsilon \ Son(x)}max(f[s][0],f[s][1]))

f[x][1]表示从以x为根的子树邀请一部分职员参会,并且x参加舞会时,快乐指数总和的最大值。此时,x的所有子节点(直接下属)都不能参会。

f[x][1]=H[x]+\sum\limits_{s\epsilon \ Son(x)}f[s][0]

我们先找到没有上司的节点root作为根,目标为max(f[root][0],f[root][1]),时间复杂度为O(N)

简单附代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Pair pair<int,int>
#define int long long
#define fir first
#define sec second
namespace fastIO{
	#define BUF_SIZE 100000
	#define OUT_SIZE 100000
	//fread->read
	bool IOerror=0;
//  inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
	inline char nc(){
		static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
		if(p1==pend){
			p1=buf;pend=buf+fread(buf,1,BUF_SIZE,stdin);
			if(pend==p1){IOerror=1;return -1;}
		}
		return *p1++;
	}
	inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
	template<class T> inline bool read(T &x){
		bool sign=0;char ch=nc();x=0;
		for(;blank(ch);ch=nc());
		if(IOerror)return false;
		if(ch=='-')sign=1,ch=nc();
		for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
		if(sign)x=-x;
		return true;
	}
	inline bool read(double &x){
		bool sign=0;char ch=nc();x=0;
		for(;blank(ch);ch=nc());
		if(IOerror)return false;
		if(ch=='-')sign=1,ch=nc();
		for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
		if(ch=='.'){
			double tmp=1; ch=nc();
			for(;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
		}
		if(sign)x=-x;
		return true;
	}
	inline bool read(char *s){
		char ch=nc();
		for(;blank(ch);ch=nc());
		if(IOerror)return false;
		for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
		*s=0;
		return true;
	}
	inline bool read(char &c){
		for(c=nc();blank(c);c=nc());
		if(IOerror){c=-1;return false;}
		return true;
	}
	template<class T,class... U>bool read(T& h,U&... t){return read(h)&&read(t...);}
	#undef OUT_SIZE
	#undef BUF_SIZE
};using namespace fastIO;using namespace std;
const int N=1e6+5;
const int mod=1e9+7;

int h[N];
bool v[N];
vector<int>son[N];
int f[N][2];


void dp(int x){
  f[x][0]=0;
  f[x][1]=h[x];
  for(int i=0;i<son[x].size();i++){
    int y=son[x][i];
    dp(y);
    f[x][0]+=max(f[y][0],f[y][1]);
    f[x][1]+=f[y][0];
  }
}
signed main(){
  //printf("%lld\n",112233+142536+445566+415263);
  int n;read(n);
  for(int i=1;i<=n;i++)read(h[i]);
  
  for(int i=1;i<n;i++){
    int x,y;read(x,y);
    v[x]=1;
    son[y].push_back(x);
  }
  int a,b;read(a,b);
  int root;
  for(int i=1;i<=n;i++){
    if(!v[i]){root=i;break;}
  }
  
  dp(root);
  printf("%lld\n",max(f[root][0],f[root][1]));
  return 0;
}

 

内容概要:本文介绍了多种开发者工具及其对开发效率的提升作用。首先,介绍了两款集成开发环境(IDE):IntelliJ IDEA 以其智能代码补全、强大的调试工具和项目管理功能适用于Java开发者;VS Code 则凭借轻量级和多种编程语言的插件支持成为前端开发者的常用工具。其次,提到了基于 GPT-4 的智能代码生成工具 Cursor,它通过对话式编程显著提高了开发效率。接着,阐述了版本控制系统 Git 的重要性,包括记录代码修改、分支管理和协作功能。然后,介绍了 Postman 作为 API 全生命周期管理工具,可创建、测试和文档化 API,缩短前后端联调时间。再者,提到 SonarQube 这款代码质量管理工具,能自动扫描代码并检测潜在的质量问题。还介绍了 Docker 容器化工具,通过定义应用的运行环境和依赖,确保环境一致性。最后,提及了线上诊断工具 Arthas 和性能调优工具 JProfiler,分别用于生产环境排障和性能优化。 适合人群:所有希望提高开发效率的程序员,尤其是有一定开发经验的软件工程师和技术团队。 使用场景及目标:①选择合适的 IDE 提升编码速度和代码质量;②利用 AI 编程助手加快开发进程;③通过 Git 实现高效的版本控制和团队协作;④使用 Postman 管理 API 的全生命周期;⑤借助 SonarQube 提高代码质量;⑥采用 Docker 实现环境一致性;⑦运用 Arthas 和 JProfiler 进行线上诊断和性能调优。 阅读建议:根据个人或团队的需求选择适合的工具,深入理解每种工具的功能特点,并在实际开发中不断实践和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值