【BZOJ2600】[Ioi2011]ricehub 双指针法

【BZOJ2600】[Ioi2011]ricehub

Description

乡间有一条笔直而长的路称为“米道”。沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数。这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L。 注意:可能有多块稻田位于同一个坐标上。 我们计划建造一个米仓用于储存尽可能多的稻米。和稻田一样,米仓将建在米道上,其坐标也是一个 1 到 L 之间的整数(含 1 和 L)。这个米仓可以建在满足上述条件的任一个位置上,包括那些原来已有一个或多个稻田存在的位置。 在收获季节,每一块稻田刚好出产一滿货车的稻米。为了将这些稻米运到米仓,需要雇用一位货车司机来运米。司机的收费是每一满货车运送一个单位的距离收取 1 元。換言之,将稻米从特定的稻田运到米仓的费用在数值上等于稻田坐标与米仓坐标之差的绝对值。 不幸的是,今年预算有限,我们至多只能花费 B 元运费。你的任务是要帮我们找出一个建造米仓的位置,可以收集到尽可能多的稻米。

Input

第一行 三个整数 R L B
接下来R行 每行一个整数 表示X[i]

Output

一个整数 最多稻米数

Sample Input

5 20 6
1
2
10
12
14

Sample Output

3
HINT
1 ≤ R ≤ 100,000
1 ≤ L ≤ 1,000,000,000
0 ≤ B ≤ 2,000,000,000,000,000

题解:网上好多用二分的,但是双指针多优美啊~

显然,如果我们确定了收获[l,r]中的所有稻田,那么将谷仓建在它们的中位数位置是最优的。所以用前缀和维护一下,就能快速求出[l,r]需要的运费,接着就能用双指针法了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,ans;
ll m;
ll x[maxn],s[maxn];
bool calc(int l,int r)
{
	int mid=(l+r)>>1;
	return (s[r]-s[mid])-(r-mid)*x[mid]+(mid-l)*x[mid]-(s[mid-1]-s[l-1])<=m;
}
inline ll rd()
{
	ll ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd(),rd(),m=rd();
	int i,j;
	for(i=j=1;i<=n;i++)
	{
		x[i]=rd(),s[i]=x[i]+s[i-1];
		for(;!calc(j,i);j++);
		ans=max(ans,i-j+1);
	}
	printf("%d",ans);
	return 0;
}
时间: 2024-10-24 07:51:17

【BZOJ2600】[Ioi2011]ricehub 双指针法的相关文章

bzoj2600 [Ioi2011]ricehub

Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L. 注意:可能有多块稻田位于同一个坐标上. 我们计划建造一个米仓用于储存尽可能多的稻米.和稻田一样,米仓将建在米道上,其坐标也是一个 1 到 L 之间的整数(含 1 和 L).这个米仓可以建在满足上述

【bzoj2096】[Poi2010]Pilots 双指针法+STL-set

题目描述 Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. 输入 输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度.第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表示难度序列. 输出

【BZOJ4653】[Noi2016]区间 双指针法+线段树

[BZOJ4653][Noi2016]区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri. 对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度.区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值. 求所有合法方案中最小

[Ioi2011]ricehub

2600: [Ioi2011]ricehub Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L. 注意:可能有多块稻

BZOJ 2600: [Ioi2011]ricehub

2600: [Ioi2011]ricehub Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 628  Solved: 325[Submit][Status][Discuss] Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ...

【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法

[BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. 他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点开始(第一天从起点一开始,第二天从起点二开始……). 而且他们给每条道路定上一个幸福的值.很显然他们每次出发都想走幸福值和最长的路线(即从起点到树上的某一点路径中最长的一条). 他

【BZOJ2282】[Sdoi2011]消防 树形DP+双指针法+单调队列

[BZOJ2282][Sdoi2011]消防 Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防业.由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何(总统竞选的国民支持率),所以只能想尽方法提高消防能力. 现在这个国家的经费足以在一条边长度和不超过s的路径(两端都是城市)上建立消防枢纽,为了尽量提高枢纽的利用率,要求其

第一篇博客园--双指针法小记

问题: 对于一个任意的自然数,问是否能将其拆分成2个或2个以上的连续自然数之和,写出所有的等式. 解题思路: 第一种解法是推导出数学公式,因为连续的自然数可以用等差数列Sn求和公式,判断可行性.公式推导以及证明过程:数学解法: 第二种解法是直接穷举解法,不过对于较大的数字复杂度O(n^2)可能不够解决,由于连续的自然数一定是递增状态,我们可以用尺取法,也就是双指针法将复杂度降低到O(n) 双指针解法: #include <bits/stdc++.h> using namespace std;

LeetCode刷题总结之双指针法

Leetcode刷题总结 目前已经刷了50道题,从零开始刷题学到了很多精妙的解法和深刻的思想,因此想按方法对写过的题做一个总结 双指针法 双指针法有时也叫快慢指针,在数组里是用两个整型值代表下标,在链表里是两个指针,一般能实现O(n)的时间解决问题,两个指针的位置一般在第一个元素和第二个元素或者第一个元素和最后一个元素,快指针在前“探路”,当符合某种条件时慢指针向前挪 盛最多水的容器 这道题其实是求最大面积,最大面积取决于较小值.初始时两指针分别位于第一和最后一个元素处,那么明确指针应该向什么方