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;
}
相关推荐
KarrySmile27 分钟前
Day04–链表–24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II
算法·链表·面试·双指针法·虚拟头结点·环形链表
花开富贵ii32 分钟前
代码随想录算法训练营二十八天|动态规划part01
java·数据结构·算法·leetcode·动态规划
啊阿狸不会拉杆32 分钟前
《Java 程序设计》第 7 章 - 继承与多态
java·开发语言·jvm·算法·intellij-idea
Deng9452013141 小时前
数独求解器与生成器(回溯算法实现)
算法·图形用户界面·matlab技术·数独谜题·求解器与生成器
淦暴尼1 小时前
银行客户流失预测分析
python·深度学习·算法
Swiler1 小时前
数据结构第1问:什么是数据结构?
数据结构·算法
Eloudy2 小时前
复矩阵与共轭转置矩阵乘积及其平方根矩阵
人工智能·算法·矩阵
m0_631354452 小时前
VTK开发day2:切片矩阵
人工智能·算法·矩阵
go54631584652 小时前
在本地环境中运行 ‘dom-distiller‘ GitHub 库的完整指南
人工智能·深度学习·神经网络·算法·矩阵·github
weixin_537590452 小时前
【任务6.13】计算肇事汽车号码
c++·算法·汽车