HDU 5303 Delicious Apples

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  i th tree is planted at position  xi , clockwise from position  0 . There are  ai  delicious apple(s) on the  i th 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?

1n,k105,ai1,a1+a2+...+an105
1L109
0x[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.
 

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;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值