HDU 5303 Delicious Apples(思维)

Delicious Apples

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 2804    Accepted Submission(s): 878


 

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.

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.

Output

Output total distance in a line for each testcase.

扫描二维码关注公众号,回复: 2203471 查看本文章

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点,顺时针标号1~l-1。有n(n<=1e5)颗苹果树,每棵树所在位置为x[i],每颗树上有苹果a[i]个,你有一个容量为k的篮子(一次最多装k个苹果),问最少路程为多少可以把所有苹果摘回家。

思路:采用dp的思想。注意到题目有a1+a2+...+an≤105 自然想到枚举每一个苹果从左边拿还是从右边拿。

于是先把每颗苹果树按x值从小到大排序,再依次把每个苹果的位置都存到数组里,然后预处理从右、左边直接拿这个苹果的需要走的路程。然后再枚举从第i+1个苹果开始从左边拿,取最小值。考虑到省路程的情况只有一种,就是走一圈。而且越拿靠近中间的苹果越好。于是再枚举一下第i+1个苹果到第i+k个苹果走一圈拿走,剩下的同上,取一个最小值。注意,如果苹果总数小于k我们是没有枚举到走一圈的情况的,所以再特判一下。

思路很好理解,但是真正到赛场上想出来还是很难。

代码:

#include<bits/stdc++.h>
#define ll long long
#define maxn 200010
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
    int x,v;
    node(){}
    node(int aa,int bb){x=aa;v=bb;}
    bool operator<(node aa)const
    {
        return x<aa.x;
    }
}a[maxn];
ll b[maxn];
int n,m,k,flag,f,g;
ll ans,tmp,cnt,l;
ll dpl[maxn],dpr[maxn];
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%d%d",&l,&n,&k);
        ans=0; f=0;g=0;
        memset(dpl,0,sizeof(dpl));
        memset(dpr,0,sizeof(dpr));
        for(int i=0;i<n;i++)
        {
            int xx,vv;
            scanf("%d%d",&xx,&vv);
            a[f++]=node(xx,vv);
        }
        sort(a,a+f);
        g=1;
        for(int i=0;i<n;i++)
        for(int j=0;j<a[i].v;j++)
        b[g++]=(ll)a[i].x;
        for(int i=1;i<g;i++)
        {
            int j=max(0,i-k);
            dpr[i]=dpr[j]+2*b[i];
        }
        for(int i=g-1;i>=1;i--)
        {
            int j=min(i+k,g);
            dpl[i]=dpl[j]+2*(l-b[i]);
        }
        for(int i=0;i<g;i++)
        {
            if(ans==0) ans=dpr[i]+dpl[i+1];
            else ans=min(ans,dpr[i]+dpl[i+1]);
        }
        for(int i=0;i+k<g;i++)
        {
            ans=min(ans,dpr[i]+dpl[i+1+k]+l);
        }
        if(g<=k) ans=min(ans,l);
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lsd20164388/article/details/81067517