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
3 2
1 3
2 1
3 2
Sample Output
由于暑假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;
}