Luogu6005 [USACO20JAN]Time is Mooney G 题解
第一眼看到题面时可能觉得需要用 dijstra 或分层图之类,但注意到数据范围很小(都是 ⩽),因此考虑好写的 DP。
首先当然需要使用邻接表存图。
不妨设 f_{i,j} 为第 i 天在第 j 个城市所获利润,易得状态转移方程:
f_{i,j}=\max(f_{i,j},f_{i-1,e[i].to})
但是这还没完,还有两个问题需要解决:
-
会以 T^2\times C 的速度扣钱。
不妨在每次外层循环后处理 ans,有:
ans=\max(ans,f[i][1]-c\times i^2); -
外层循环没有明确边界。
最大是 1000,以此为边界即可。注意:有的人可能习惯设 N=1010 ,这会导致 i=N 时 RE,应该 N-10。
View code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ri register int
#define il inline
const int INF=0x7fffffff,N=1010;
int n,m,c,ans=0;
int v[N];
int cnt,head[N];
int f[N][N];
struct Edge{
int to,nxt;
}e[N<<2];
il ll read(){
ll x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
il void add(int u,int v){
e[++cnt]=(Edge){v,head[u]};
head[u]=cnt;
}
signed main(){
memset(f,-1,sizeof(f));
n=read(),m=read(),c=read();
for(ri i=1;i<=n;i++)
v[i]=read();
for(ri i=1;i<=m;i++){
int u=read(),v=read();
add(u,v);//有向图
}
f[0][1]=0;
for(ri i=1;i<=N-10;i++){
for(ri j=1;j<=n;j++){
for(ri k=head[j];k;k=e[k].nxt){
if(~f[i-1][e[k].to])
f[i][j]=max(f[i][j],f[i-1][e[k].to]+v[j]);
}
}
ans=max(ans,f[i][1]-(c*i*i));
}
printf("%lld",ans);
return 0;
}
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从“看懂世界”到“改造世界”:AI发展的四个阶段你了解了吗?
· 协程本质是函数加状态机——零基础深入浅出 C++20 协程
· 编码之道,道心破碎。
· 记一次 .NET 某发证机系统 崩溃分析
· 微服务架构学习与思考:SOA架构与微服务架构对比分析
· 历时半年,我将一个大型asp.net的零代码快速开发平台转成了java
· C#实现语音预处理:降噪、静音检测、自动增益(附Demo源码)
· 推荐五大AI+MCP自动化测试工具!
· 记一次 .NET 某无语的电商采集系统 CPU爆高分析
· Spring Boot 启动优化实践