Delicious Apples
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
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
刚看这个题的时候头都大了,感觉贪心起来好复杂啊。情况太多,不是很好处理。但是多列几种情况就会发现,绕圈的话最多只需要绕一次,而且还必须是左半圈的苹果数加上右半圈的苹果数小于K时才有可能需要绕圈(自己举两个例子就明白了)。所以对所有需要绕圈情况枚举判断看看是不是更优即可。因为苹果总数不超过1e5,所以可以将苹果离散化,这样更好处理。用dpl[]和dpr[]分别表示取到某个苹果所需要的距离,这里需要用到贪心,想一想再不考虑其他情况下怎么取苹果才最优。例如两个苹果树1 k+1和2 k, 明显是要优先将远处的苹果取为一篮子,依据这个规则更新dp数组即可。代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <bitset>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define maxn 100010
#define ll long long
using namespace std;
long long dpl[maxn],dpr[maxn],dis[maxn];
vector<int> vl,vr;
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int l,n,k,cnt=1;
vl.clear();
vr.clear();
cin>>l>>n>>k;
for(int i=0;i<n;i++)
{
int a,b;
cin>>a>>b;
for(int i=0;i<b;i++)
{
dis[cnt++]=a;
if(a<=(l/2))
{
vl.push_back(a);
}
else
{
vr.push_back(l-a);
}
}
}
sort(vl.begin(),vl.end());
sort(vr.begin(),vr.end());
dpl[0]=0;
dpr[0]=0;
for(int i=0;i<vl.size();i++)
{
if(i+1<=k)
{
dpl[i+1]=vl[i];
}
else
{
dpl[i+1]=vl[i]+dpl[i+1-k];
}
}
for(int i=0;i<vr.size();i++)
{
if(i+1<=k)
{
dpr[i+1]=vr[i];
}
else
{
dpr[i+1]=vr[i]+dpr[i+1-k];
}
}
long long ans=dpl[vl.size()]*2+dpr[vr.size()]*2;
for(int i=0;i<=k&&i<=vl.size();i++)
{
if(dpl[vl.size()-i]*2+dpr[max(0,(int)vr.size()-(k-i))]*2+l<ans)
{
ans=dpl[vl.size()-i]*2+dpr[max(0,(int)vr.size()-(k-i))]*2+l;
}
}
cout<<ans<<endl;
}
return 0;
}