http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?cid=12578&pid=1015&ojid=0
题意:n颗苹果树在周长为l的环形路上,你处在环形路的0位置,手里有一个容量为k(可以装k个苹果)的篮子,问最少走多短的距离可以把苹果都摘光。对不到半圈的那些树上的苹果,肯定是原路返回短,但也有可能走一圈,如果你要走一圈肯定是尽可能的把容量k装满。本题是把苹果离散化了(把苹果从树上摘下来)。right-(k-i)可能为负需要与0比
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll disl[maxn],disr[maxn],loc[maxn];
vector<ll>lloc,rloc;
int main()
{
ll t,l,n,k,pos,num,i,j,left,right,ans,cnt,pinkl,pinkr;
scanf("%lld",&t);
while(t--)
{
lloc.clear();
rloc.clear();
memset(disl,0,sizeof(disl));
memset(disr,0,sizeof(disr));
scanf("%lld%lld%lld",&l,&n,&k);
cnt=0;
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&pos,&num);
for(j=1;j<=num;j++)
{
loc[cnt++]=pos;
}
}
for(i=0;i<cnt;i++)
{
if(2*loc[i]<l)
lloc.push_back(loc[i]);
else
rloc.push_back(l-loc[i]);
}
sort(lloc.begin(),lloc.end());
sort(rloc.begin(),rloc.end());
left=lloc.size();
right=rloc.size();
for(i=0;i<left;i++)
disl[i+1]=((i+1)<=k?lloc[i]:disl[i+1-k]+lloc[i]);
for(i=0;i<right;i++)
disr[i+1]=((i+1)<=k?rloc[i]:disr[i+1-k]+rloc[i]);
ans=(disl[left]+disr[right])*2;
for(i=0;i<=k&&i<=left;i++)
{
pinkl=left-i;
pinkr=max(0,(int)(right-(k-i)));
ans=min(ans,2*(disl[pinkl]+disr[pinkr])+l);
}
printf("%lld\n",ans);
}
}