道路游戏——题解
单调队列优化-道路游戏
[NOIP2009 普及组] 道路游戏
题目描述
小新正在玩一个简单的电脑游戏。
游戏中有一条环形马路,马路上有
游戏过程中,每个单位时间内,每段马路上都会出现一些金币,金币的数量会随着时间发生变化,即不同单位时间内同一段马路上出现的金币数量可能是不同的。小新需要机器人的帮助才能收集到马路上的金币。所需的机器人必须在机器人工厂用一些金币来购买,机器人一旦被购买,便会沿着环形马路按顺时针方向一直行走,在每个单位时间内行走一次,即从当前所在的机器人工厂到达相邻的下一个机器人工厂,并将经过的马路上的所有金币收集给小新,例如,小新在
以下是游戏的一些补充说明:
-
游戏从小新第一次购买机器人开始计时。
-
购买机器人和设定机器人的行走次数是瞬间完成的,不需要花费时间。
-
购买机器人和机器人行走是两个独立的过程,机器人行走时不能购买机器人,购买完机器人并且设定机器人行走次数之后机器人才能行走。
-
在同一个机器人工厂购买机器人的花费是相同的,但是在不同机器人工厂购买机器人的花费不一定相同。
-
购买机器人花费的金币,在游戏结束时再从小新收集的金币中扣除,所以在游戏过程中小新不用担心因金币不足,无法购买机器人而导致游戏无法进行。也因为如此,游戏结束后,收集的金币数量可能为负。
现在已知每段马路上每个单位时间内出现的金币数量和在每个机器人工厂购买机器人需要的花费,请你告诉小新,经过
输入格式
第一行
接下来的
述了
最后一行,有
输出格式
共一行,包含
样例 #1
样例输入 #1
2 3 2
1 2 3
2 3 4
1 2
样例输出 #1
5
提示
对于
对于
对于
NOIP 2009 普及组 第四题
题解
首先本题是最优性问题,容易想到动态规划,那么我们来分析此题的动态规划做法
状态刻画
最朴素的想法:设
我们发现,在转移的时候,最后一个维度可以枚举消掉,故略去
最终得到
状态转移
考虑转移。明显
那么有:
其中
这里为了代码的方便,我们采取将点权下放到边权的形式,将边
为了用模运算简单处理环,我们需要将编号从零开始,所以读入时不会有任何改变
下一步,我们考虑如何将
将
将
考虑进行转化,如果我们设
那么
接着,状态转移方程就可以改写成:
观察到
需要注意的是我们在处理
到此,我们得到了一个复杂度为垃圾算法
转移优化
观察这个DP式子,如果我们把
记
状态转移方程就是
考虑如何优化掉这个式子,这个样子非常像单调队列优化,只是我们如何定下单调队列优化的策略
考虑两个决策
因为我们的决策涉及到了两个变量,就需要多个单调队列,并且我们需要考虑的是,一个决策
注意观察原来的
这启发我们按照
#include<bits/stdc++.h>
using namespace std;
#define N 1005
int n,m,p,dp[N],a[N][N],f[N][N],cost[N],l[N],r[N];
int pos(int x){return (x%n+n)%n;}
int get(int x,int y){return ((y-x)%n+n)%n;}
struct node{
int pos,num;
}rec[N][N];
signed main(){
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&a[j][i]);
if(i==n)a[j][0]=a[j][i];
}
for(int i=1;i<=m;i++)
for(int j=0;j<n;j++)
f[i][j]=f[i-1][pos(j-1)]+a[i][j];
for(int i=0;i<n;i++){
scanf("%d",&cost[i]);
rec[i][++r[i]].num=-cost[i],l[i]++;
}
memset(dp,-0x3f,sizeof dp);
dp[0]=0;
for(int i=1;i<=m;i++){
for(int j=0;j<n;j++){
int id=get(i,j);
while(l[id]<=r[id] && rec[id][l[id]].pos+p<i) l[id]++;
if(l[id]<=r[id])
dp[i]=max(dp[i],rec[id][l[id]].num+f[i][j]);
}
for(int j=0;j<n;j++){
int id=get(i,j);
while(l[id]<=r[id] && rec[id][r[id]].num<=dp[i]-f[i][j]-cost[j])
r[id]--;
rec[id][++r[id]]=(node){i,dp[i]-f[i][j]-cost[j]};
}
}
printf("%d\n",dp[m]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!