Delicious Apples
Problem Description
There are n apple
trees planted along a cyclic road, which is L metres
long. Your storehouse is built at position 0 on
that cyclic road.
The ith tree is planted at position xi, clockwise from position 0. There are ai delicious apple(s) on the ith tree.
You only have a basket which can contain at most K apple(s). You are to start from your storehouse, pick all the apples and carry them back to your storehouse using your basket. What is your minimum distance travelled?
1≤n,k≤105,ai≥1,a1+a2+...+an≤105
1≤L≤109
0≤x[i]≤L
There are less than 20 huge testcases, and less than 500 small testcases.
The ith tree is planted at position xi, clockwise from position 0. There are ai delicious apple(s) on the ith tree.
You only have a basket which can contain at most K apple(s). You are to start from your storehouse, pick all the apples and carry them back to your storehouse using your basket. What is your minimum distance travelled?
1≤n,k≤105,ai≥1,a1+a2+...+an≤105
1≤L≤109
0≤x[i]≤L
There are less than 20 huge testcases, and less than 500 small testcases.
Input
First line: t,
the number of testcases.
Then t testcases follow. In each testcase:
First line contains three integers, L,n,K.
Next n lines, each line contains xi,ai.
Then t testcases follow. In each testcase:
First line contains three integers, L,n,K.
Next n lines, each line contains xi,ai.
Output
Output total distance in a line for each testcase.
Sample Input
2 10 3 2 2 2 8 2 5 1 10 4 1 2 2 8 2 5 1 0 10000
Sample Output
18 26
题目大意:给定一个环形道路长度为L,以及环形道路下标为0处为起始点,在环形道路上距
离起始点Xi位置种植一颗苹果树,该树有a个苹果,篮子的最大容量为K,那么求摘
完全部苹果所需的最短距离。
思路:最后一篮想了多种可能性,结果太乱不知道怎么解决了。。。
将环形圈分成两个半圆,在每个半圆里尽可能的装苹果,但是,最后一篮苹果可能是绕了整个
环形圈走的,所以这里需要特殊处理一下。
刚开始的思路就卡在最后一篮苹果上了,看了别人的代码,如果自己写可能会写的很复杂,
把每个苹果都纳入数组,求出从两个方向到达原点最近的距离,然后在最后一个篮子上进行枚举。
很精妙的思路和代码。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 100005
int Left[M],Right[M],numl,numr;
int n,k,l;
long long s_l[M],s_r[M],ans;
void slove()
{
for(int i=1;i<=numl;i++){
if(i<=k)
s_l[i]=Left[i];
else
s_l[i]=Left[i]+s_l[i-k];
}
for(int i=1;i<=numr;i++){
if(i<=k)
s_r[i]=Right[i];
else
s_r[i]=Right[i]+s_r[i-k];
}
ans=(s_r[numr]+s_l[numl])*2;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&l,&n,&k);
memset(s_l,0,sizeof(s_l));
memset(s_r,0,sizeof(s_r));
numl=numr=0;
for(int i=1;i<=n;i++){
int len,num;
scanf("%d%d",&len,&num);
for(int j=1;j<=num;j++){
if(len*2<l)
Left[++numl]=len;
else
Right[++numr]=l-len;
}
}
sort(Left+1,Left+1+numl);
sort(Right+1,Right+1+numr);
slove();
for(int i=0;i<=k;i++){
long long ll = 2*(s_l[numl-i]+s_r[max(0,numr-k+i)]);
ans=min(ans,ll+l);
}
printf("%lld\n",ans);
}
return 0;
}