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;
}
相关推荐
QxQ么么4 小时前
移远通信(桂林)26校招-助理AI算法工程师-面试纪录
人工智能·python·算法·面试
Mz12217 小时前
day05 移动零、盛水最多的容器、三数之和
数据结构·算法·leetcode
SoleMotive.7 小时前
如果用户反映页面跳转得非常慢,该如何排查
jvm·数据库·redis·算法·缓存
念越7 小时前
判断两棵二叉树是否相同(力扣)
算法·leetcode·入门
ghie90908 小时前
线性三角波连续调频毫米波雷达目标识别
人工智能·算法·计算机视觉
却话巴山夜雨时i8 小时前
74. 搜索二维矩阵【中等】
数据结构·算法·矩阵
sin_hielo8 小时前
leetcode 3512
数据结构·算法·leetcode
_F_y8 小时前
二分:二分查找、在排序数组中查找元素的第一个和最后一个位置、搜索插入位置、x 的平方根
c++·算法
Elias不吃糖8 小时前
LeetCode--130被围绕的区域
数据结构·c++·算法·leetcode·深度优先