Hdu5303 Delicious Apples

题意:给定一个环形道路长度为L,以及环形道路下标为0处为起始点,在环形道路上距离起始点xi位置种植一颗苹果树,该树有a个苹果,篮子的最大容量为k,那么求摘完全部苹果所需的最短距离。

思路:分析这道题发现,如果走半圈以内就可以取k个就不要走一圈,一直先取到里0点最远的剩余时,分析如果左右半圈都小于k时比较是分别走还是一圈走下来的情况,就是一种贪心,但还要讨论最后的情况。。。还是看代码的解释吧

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<vector>
#include<cstdio>
#include<time.h>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<string.h>
#include<algorithm>
#define ll long long
#define PI acos(-1.0)
using namespace std;
ll L,n,k;
vector<ll>l,r;
struct node
{
    ll pos,ge;
}a[100005];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&L,&n,&k);
        l.clear();
        r.clear();
        l.push_back(0);//先放入0,方便后面
        r.push_back(0);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&a[i].pos,&a[i].ge);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=a[i].ge;j++)
            {
                if(a[i].pos*2<L) l.push_back(a[i].pos);//左右半圈分别放入其中,且离散化处理
                else r.push_back(L-a[i].pos);
            }
        }
        sort(l.begin(),l.end());
        sort(r.begin(),r.end());
        ll e=l.size()-1,t=r.size()-1;
        for(int i=k;i<l.size();i++) l[i]+=l[i-k];//当i<k是花费就是l[i],大于k时就要叠加后边新的k
        for(int i=k;i<r.size();i++) r[i]+=r[i-k];
        ll ans=(l[e]+r[t])*2;//不走整一圈的情况
        for(ll x=0;x<=k&&x<=e+1;x++)//当左半圈剩余x,有半圈剩余k-x时,找最小值
        {
            ll p=e-x;
            ll q=max((ll)0,t-(k-x));
            ans=min(ans,(l[p]+r[q])*2+L);
        }
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/snayf/article/details/81105896