usaco2013 mar【懒惰的奶牛】

拜拜、爱过 提交于 2020-07-25 18:10:17

描述

  夏天又到了,奶牛贝里斯开始变得非常懒惰。他想要站在一个地方,然后只走很少的一段路,就能吃到尽可能多的美味的青草。
  有N块草坪排列在一条直线上,第i个草坪拥有g_i数量的青草,第i个草坪所在的位置是x_i。奶牛贝里斯想要在直线上选择一个点作为他的初始点(初始点有可能和草坪的位置重合),这样他就能吃到以这个点为中点距离不超过K的位置上的所有青草。
  如果初始点可以自由选择的话,请帮助贝里斯计算他最多能吃到的青草的数量。

输入输出格式

输入

  第一行是两个正整数,表示N和K。
  第2行到第N+1行,每行两个整数,第i行的两个整数表示第i个草坪的g_i和x_i。

输出

  输出贝里斯最多能吃到的青草数量。

输入输出样例

样例输入1

4 3
4 7
10 15
2 2
5 1

样例输出1

11

样例说明

  如果贝里斯将初始点选择在x=4的位置,那么他可以吃到x=1,x=2和x=7这三个地方的青草,总共是11。

数据规模

  1<=N<=100000,1<=g_i<=10000,0<=x_i<=1000000,1<=k<=2000000。

解题思路

  刚开始我想用前缀和,然后每次枚举区间比较最大值,但是我最后还是用的类似于队列的东西来做(因为老师强制性),每次用一个左端点和右端点移动就行。

题解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k,maxn,ans;
 4 int mp[5000001];//存青草地的 
 5 int read()//快读 
 6 {
 7     int x=0,f=1;
 8     char ch=getchar();
 9     while(ch<'0'||ch>'9'){
10         if(ch=='-')
11             f=-1;
12         ch=getchar();
13     }
14     while(ch>='0'&&ch<='9'){
15         x=(x<<1)+(x<<3)+(ch^48);
16         ch=getchar();
17     }
18     return x*f;
19 }
20 int main()
21 {
22     cin>>n>>k;
23     k*=2;//方便后续操作 
24     for(int i=1;i<=n;i++)
25     {
26         int x,w;
27         w=read();
28         x=read();
29         mp[x]=w;//存入 
30     }
31     int l=0,r=k,ans=0;//l一定要从0开始,我之前一个多小时WA就是因为它 
32     for(int i=l;i<=r;i++)
33     {
34         ans+=mp[i];//求区间和 
35     }
36     maxn=max(maxn,ans);
37     while(r<=5000001)//因为不知道大小,只能硬枚举 
38     {
39         ans-=mp[l];//减去左端点的 
40         l++;//右移 
41         r++;//右移 
42         ans+=mp[r];//加上右端点的 
43         maxn=max(maxn,ans);//取最优解 
44     }
45     cout<<maxn;//输出 
46 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!