AcWing 289. 环路运输,《算法竞赛进阶指南》,单调队列优化dp,滑动窗口求最大值,环形与后效性处理

289. 环路运输 - AcWing题库

在一条环形公路旁均匀地分布着 N 座仓库,编号为 1∼N,编号为 i 的仓库与编号为 j 的仓库之间的距离定义为 dist(i,j)=min(|i−j|,N−|i−j|),也就是逆时针或顺时针从 i 到 j 中较近的一种。

每座仓库都存有货物,其中编号为 i 的仓库库存量为 Ai。

在 i 和 j 两座仓库之间运送货物需要的代价为 Ai+Aj+dist(i,j)。

求在哪两座仓库之间运送货物需要的代价最大。

输入格式

第一行包含一个整数 N。

第二行包含 N 个整数 A1∼AN。

输出格式

输出一个整数,表示最大代价。

数据范围

2≤N≤106,

1≤Ai≤107

输入样例:
复制代码
5
1 8 6 2 5
输出样例:
复制代码
15

解析:单调队列,动规

如果使用暴力的方法我们可以使用两个循环,一个枚举i,另一个枚举j

仔细观察这道题,我们可以发现一下性质
dist(i,j)=min(|i−j|,N−|i−j|)在 | i - j |<n/2 情况下,dist(i,j)=i-j;同时代价 Ai+Aj+dist(i,j) 可以转化成 Ai+i+Aj-j。

所以我们只需要枚举 i ,然后求出 i 右边 len=n/2 的范围内的最大的 Aj-j 即可

到这里可以看出来这可以单调队列来解决

cpp 复制代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 2e6 + 5;
int n, m;
int w[N], q[N];

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &w[i]);
		w[i + n] = w[i];
	}
	int hh = 0, tt = -1;
	int len = n / 2;
	int ret = 0;
	for (int i = 1; i <= 2 * n; i++) {
		if (hh <= tt && i - q[hh] > len)hh++;
		ret = max(ret, w[i] + w[q[hh]] + i - q[hh]);
		while (hh <= tt &&w[q[tt]]- q[tt] <= w[i] - i)tt--;//这一步让队列从左往右变得单调,且左边的值最大
		q[++tt] = i;
	}
	printf("%d\n", ret);
	return 0;
}
相关推荐
int型码农4 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
UFIT4 小时前
NoSQL之redis哨兵
java·前端·算法
喜欢吃燃面4 小时前
C++刷题:日期模拟(1)
c++·学习·算法
SHERlocked934 小时前
CPP 从 0 到 1 完成一个支持 future/promise 的 Windows 异步串口通信库
c++·算法·promise
怀旧,5 小时前
【数据结构】6. 时间与空间复杂度
java·数据结构·算法
积极向上的向日葵5 小时前
有效的括号题解
数据结构·算法·
GIS小天5 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月7日第101弹
人工智能·算法·机器学习·彩票
_Itachi__5 小时前
LeetCode 热题 100 74. 搜索二维矩阵
算法·leetcode·矩阵
不忘不弃5 小时前
计算矩阵A和B的乘积
线性代数·算法·矩阵
不爱写代码的玉子5 小时前
HALCON透视矩阵
人工智能·深度学习·线性代数·算法·计算机视觉·矩阵·c#