D. Single-use Stones
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
A lot of frogs want to cross a river. A river is ww units width, but frogs can only jump ll units long, where l<wl<w. Frogs can also jump on lengths shorter than ll. but can't jump longer. Hopefully, there are some stones in the river to help them.
The stones are located at integer distances from the banks. There are aiai stones at the distance of ii units from the bank the frogs are currently at. Each stone can only be used once by one frog, after that it drowns in the water.
What is the maximum number of frogs that can cross the river, given that then can only jump on the stones?
Input
The first line contains two integers ww and ll (1≤l<w≤1051≤l<w≤105) — the width of the river and the maximum length of a frog's jump.
The second line contains w−1w−1 integers a1,a2,…,aw−1a1,a2,…,aw−1 (0≤ai≤1040≤ai≤104), where aiai is the number of stones at the distance ii from the bank the frogs are currently at.
Output
Print a single integer — the maximum number of frogs that can cross the river.
Examples
input
Copy
10 5
0 0 1 0 2 0 0 1 0
output
Copy
3
input
Copy
10 3
1 1 1 1 2 1 1 1 1
output
Copy
3
Note
In the first sample two frogs can use the different stones at the distance 55, and one frog can use the stones at the distances 33 and then 88.
In the second sample although there are two stones at the distance 55, that does not help. The three paths are: 0→3→6→9→100→3→6→9→10, 0→2→5→8→100→2→5→8→10, 0→1→4→7→100→1→4→7→10
原题链接:http://codeforces.com/contest/965/problem/D
题目意思是一群青蛙想过河,但是跳不过去,刚好河上有许多石头,青蛙可以通过石头过河,一个石头只能使用一次,
问有多少只青蛙可以过河。
我的想法是每次跳当前距离最远处,然后从最远的地方开始往后找能跳的石头,能跳多少只青蛙取决于这条路上石头的最小值
#include<bits/stdc++.h>
using namespace std;
int w,l;
int a[100010];
int b[100010]; ///b[k]保存的是小于等于k距离的石头在何处
int judge(int i,int num) ///返回值是能有多少只青蛙过河,i是当前距离,num是当前最多青蛙数量
{
int k = i + l;
if(k >= w)
return num;
while(a[k] <= 0 && k > i) ///找一块能跳的最远的石头,并且位置要大于起点
{
b[k] = b[b[k]]; ///顺便更新b[k]的值,可以缩短每次查找的时间
k = b[k];
}
if(k <= i)
return 0;
int cnt = judge(k,min(num,a[k])); ///找一条路径上的最小值
a[k] -= cnt; ///更新距离为k的石头的个数
if(a[k] == 0)
b[k] = b[k - 1];
return cnt;
}
int main()
{
scanf("%d %d",&w,&l);
b[0] = -1;
for(int i = 1;i < w;i ++)
{
scanf("%d",&a[i]);
if(a[i] == 0)
b[i] = b[i - 1];
else
b[i] = i;
}
int cnt = 0;
int sum = 0;
while(1)
{
sum = judge(0,100000); ///一开始距离为0,青蛙有无穷多只
if(sum == 0) ///如果没有一只青蛙能过河就结束
break;
cnt += sum;
}
cout<<cnt<<endl;
return 0;
}
.