HDU 5303 Delicious Apples(贪心 + 双肩包 2015多校啊)
HDU 5303 Delicious Apples(贪心 + 背包 2015多校啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5303
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.
Thei 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 mostK 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.
The
You only have a basket which can contain at most
There are less than 20 huge testcases, and less than 500 small testcases.
Input
First line: t ,
the number of testcases.
Thent testcases
follow. In each testcase:
First line contains three integers,L,n,K .
Nextn lines,
each line contains xi,ai .
Then
First line contains three integers,
Next
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
Source
2015 Multi-University Training Contest 2
题意:
一个长为 L 的环行路线,有 n 颗苹果树,每颗苹果树上有 a[i] 个苹果,一个人在0点(仓库的位置),他有一个篮子,篮子每次最多只能装 k 个苹果,求要装完所有的苹果并且回到仓库的最小路程;给出的苹果树坐标是按顺时针的!
官方题解:
PS:
贪心,把环从中间分为两段,分左右两条线;
利用 a[i] 数组记录每个苹果所在的苹果树的位置,之后再将苹果按照所在的位置进行排序一下,
所以我们就知道了每次摘 k 个苹果的路程是最远的那个苹果所在的位置。
再用 sum[i] 表示摘第 i 个苹果时的最小代价和,
根据背包的思想得到:
if ( i <= k )
sum[i] = d[i]
else
sum[i] = d[i] + sum[i-k]注意:
还有一种情况是在最后当剩下的苹果少于等于 k 个时,或许一次性绕环一圈拿完最后的k个所需的路程更少;
枚举剩下的最后k个!
代码如下:
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define LL __int64 const int maxn = 100047; vector <int> v1, v2; LL a[maxn]; LL sum1[maxn], sum2[maxn]; int main() { int t; int n, k, l; scanf("%d",&t); while(t--) { scanf("%d%d%d",&l,&n,&k); int pos, num; int h = 0; for(int i = 0; i < n; i++) { scanf("%d%d",&pos,&num); for(int j = 0; j < num; j++) { a[++h] = pos; } } k = min(h,k); v1.clear(); v2.clear(); for(int i = 1; i <= h; i++) { if(a[i]*2 < l) { v1.push_back(a[i]); } else { v2.push_back(l - a[i]); } } memset(sum1,0,sizeof(sum1)); memset(sum2,0,sizeof(sum2)); sort(v1.begin(), v1.end()); sort(v2.begin(), v2.end()); int len1 = v1.size(), len2 = v2.size(); for(int i = 0; i < len1; i++) { int id = i+1; if(id <= k) { sum1[id] = v1[i]; } else { sum1[id] = v1[i]+sum1[id-k]; } } for(int i = 0; i < len2; i++) { int id = i+1; if(id <= k) { sum2[id] = v2[i]; } else { sum2[id] = v2[i]+sum2[id-k]; } } LL ans = 2*(sum1[len1]+sum2[len2]);//来回 int t1, t2; for(int i = 0; i <= k && i <= len1; i++) { t1 = len1 - i; t2 = len2-(k-i); if(t2 < 0) { t2 = 0; } ans = min(ans,2*(sum1[t1]+sum2[t2])+l);//最后不足k个绕行一圈全部摘走 } printf("%I64d\n",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。