题解:AT_abc188_e [ABC188E] Peddler

看各位大佬用的都是排序+dp,让我来一发玄学时间复杂度的dfs+dp。

dfs 得先设参数,我们设 dfs(p,minn,fa)\operatorname{dfs(p,minn,fa)} 表示当前走到第 p\operatorname{p} 个点,走过的价格最小值为 minn\operatorname{minn} ,上一个走过的节点为 fafa

接着是 dp,我们设 dp[p]\operatorname{dp[p]} 表示走到 p\operatorname{p} 点能获得的最大利润。这样我们就可以写出方程: d p [ i ] = max ( d p [ f a ] , a [ p ] - m i n n )\operatorname{dp[i]=\max(dp[fa],a[p]-minn)}

于是,这道题就做完了。

注意防爆要开longlong

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

typedef long long LL;

LL n,m;
vector<LL> edge[200010];
LL a[200010];
LL minsj[200010];
LL dp[200010];
LL ans=-1e9;

void dfs(LL p,LL minn,LL fa)
{
	bool flg=true;
	LL maxn=max(dp[fa],a[p]-minn);
	minn=min(minn,a[p]);
	if(minsj[p]>minn)
	{
		minsj[p]=minn;
		flg=false;
	}
	if(dp[p]<maxn)
	{
		dp[p]=maxn;
		flg=false;
	}
	if(flg)
	{
		return;
	}
	for(LL i=0;i<edge[p].size();i++)
	{
		dfs(edge[p][i],minn,p);
	}
}

int main()
{
	cin>>n>>m;
	for(LL i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(LL i=1;i<=m;i++)
	{
		LL x,y;
		cin>>x>>y;
		edge[x].push_back(y);
	}
	memset(dp,-0x3f,sizeof(dp));
	memset(minsj,0x3f,sizeof(minsj));
	for(LL i=1;i<=n;i++)
	{
		dfs(i,1e18,0);
	}
	for(LL i=1;i<=n;i++)
	{
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	return 0;
}
posted @   xlaser  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示