大战!贪心!SHU1951 Apple Trees

Description

小Y在x轴上种了好多苹果树,第i棵苹果树在p[i]的位置上,树上有a[i]个苹果。
现在小Y在坐标原点,拿着一个容量为K的篮子。
由于小Y很懒,他想求出最少移动多少距离才能够把所有树上的苹果摘下来并且运送到坐标原点。

Input

多组数据,第一行有一个整数T表示数据组数。(T <= 20)
之后有T组数据,每组数据第一行为两个整数N和K,表示苹果树的数量和篮子的容量。
(1 <= N <= 1000, 1 <= K <= 100000)
接着有N行,每行有两个整数 p[i] 和 a[i] 分别表示苹果树的坐标及苹果的数量。
(0 <= p[i] <= 1000, 1 <= a[i] <= 1000)

Output

对于每组数据,输出一行整数,表示小Y最少需要移动的距离。

Sample Input

1
3 2
1 3
2 1
3 2

Sample Output

12


由于暑假ACM集训逃了不少(又是这个原因QAQ),所以就连最基本的贪心算法都没有get过,不过这类的题我看到一般都有思路,所以也没有坑死自己过,在队友的嘴里才知道,啊这是贪心啊!

下面引用《挑战程序设计竞赛》中对贪心法的一句介绍,方便自己查阅。

贪心法就是遵循某种规则,不断贪心地选取当前最优策略的算法设计。

接下来讲一下这道题,这道题出自秋季学期的一次个人赛,当时没有想法,然后这次出现在了思维实训中,当时的想法是这么简单的题我秋季竟然不会做!然后信心满满地写,最后一共WA了7次,哈哈哈哈哈!

我没注意到的坑点主要是以下2点:

1.应该从最远的地方开始拿苹果,而不是最近的,以避免最后拿不满篮子的情况下还要跑到最远的地方去。

2.因为要从最远的依次向最近的拿苹果,所以要用结构体定义苹果树,然后根据位置排序。


#include<iostream>
#include<algorithm>
using namespace std;
struct Apple
{
    int d,num;
};
bool cmp(Apple a,Apple b)
{
    return a.d<b.d;
}
int main(void)
{
    int b,l,t,i,n,k,far;
    Apple apple[1005];
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        b=0;
        l=0;
        for(i=1;i<=n;i++)
            cin>>apple[i].d>>apple[i].num;
        i=n;
        far=n;
        sort(apple+1,apple+n+1,cmp);
        while(apple[1].num!=0)
        {
            if(apple[i].num>k-b)
            {
                apple[i].num-=k-b;
                b=0;
                l+=apple[far].d*2;
                far=i;
            }
            else if(apple[i].num==k-b)
            {
                l+=apple[far].d*2;
                b=0;
                apple[i].num=0;
                i--;
                far=i;
            }
            else
            {
                b+=apple[i].num;
                apple[i].num=0;
                if(i==1)
                    l+=apple[far].d*2;
                i--;
            }
        }
        cout<<l<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值