CF459E-DP

CF459E-DP

核心代码15行

思路

观察数据范围,我们建m层分层图跑最短路想到DP。

DP最大的特点就是无后效性。那么我们这一题哪个条件无后效性呢?

发现DP值一定从边权小于当前点的位置转移而来

这不就无后效性了?我们按边权将所有边排序即可。

然后,枚举边,将DP值记录到点上,每次用起始点的dp值加1更新到达点的dp值。最后输出dp值最大的即可。

然后,您会发现第一个样例过不去。

因为题目要求边权严格递增,所以我们需要同时将边权相同的边用上次的dp值更新,即我们需要临时记录一下。

样例非常良心。

实现

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read(){
	int w=0,x=0;char c=getchar();
	while(!isdigit(c))w|=c=='-',c=getchar();
	while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return w?-x:x;
}
namespace star
{
	const int maxn=3e5+10;
	int n,m,f[maxn],g[maxn];
	struct edge{
		int u,v,val;
		inline bool operator < (const edge &zp)const{return val<zp.val;}
	}e[maxn];
	inline void work(){
		n=read();m=read();
		for(int i=1;i<=m;i++)e[i].u=read(),e[i].v=read(),e[i].val=read();
		sort(e+1,e+1+m);
		for(int i=1,j;i<=m;i=j+1){
			j=i;
			while(e[j+1].val==e[i].val)j++;
			for(int k=i;k<=j;k++) g[e[k].u]=f[e[k].u],g[e[k].v]=f[e[k].v];//只有这些dp值要用
			for(int k=i;k<=j;k++) f[e[k].v]=max(f[e[k].v],g[e[k].u]+1);
		} 
		int ans=0;
		for(int i=1;i<=n;i++) ans=max(ans,f[i]);
		printf("%d",ans);
	}
}
signed main(){
	star::work();
	return 0;
}

postscripts

目前rank1,可能只是因为写的人少。

是一道不错的DP练手题。

posted @   Star_Cried  阅读(136)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示