2015 多校联赛 ——HDU5303(贪心)
2015-07-25 09:44
393 查看
Delicious Apples
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1371 Accepted Submission(s): 448
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.
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
Author
XJZX
Source
2015 Multi-University Training Contest 2
题意:给定一个环,以下标为处为起始点,距离起始点Xi位置种植一颗苹果树,该树有a个苹果,篮子的最大容量为K,那么求摘完全部苹果所需的最短距离。
当时大致知道方向,但是没想到具体方法。首先贪心左右半边,推出len-k时的最短路程,最后则可以直接走一圈取完。然后再与左右分别取相比较,取较小。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX 100050 long long sum_left[MAX]; long long sum_right[MAX]; int l[MAX],r[MAX]; long long ans; int Left,Right; int n,k,len,T,a,b; int main() { scanf("%d",&T); while(T--) { memset(sum_left,0,sizeof(sum_left)); memset(sum_right,0,sizeof(sum_right)); scanf("%d%d%d",&len,&n,&k); Left=0,Right=0; for(int i=0; i<n; i++) { scanf("%d%d",&a,&b); for(int j=0; j<b; j++) { if(a*2<len) l[++Left]=a; else r[++Right]=len-a; } } sort(l+1,l+Left+1); sort(r+1,r+Right+1); for(int i=1; i<=Left; i++) { if(i<=k) sum_left[i]=l[i]; else sum_left[i]=sum_left[i-k]+l[i]; } for(int i=1; i<=Right; i++) { if(i<=k) sum_right[i]=r[i]; else sum_right[i]=sum_right[i-k]+r[i]; } ans=(sum_left[Left]+sum_right[Right])*2; for(int i=0; i<=k && i <= Left; i++) { long long lll = (sum_left[Left-i]+sum_right[max(0,Right-(k-i))])*2; ans=min(ans,len+lll); } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- linux下为分区设置卷标
- Xamarin.Android开发实践(十一)
- @[Java]读取文件方法大全
- 04-树7. Search in a Binary Search Tree (25)
- window.showModalDialog以及window.open用法简介
- POJ 1321 棋盘问题
- 向设计师推荐的书籍
- IOS学习整理(一)视图层次结构与视图控制器
- Ubuntu12.04 安装 LAMMPS GPU 并行版
- linux下查看硬件架构
- Xamarin.Android开发实践(十)
- 渐开线函数工具
- PAT (Advanced Level) 1040. Longest Symmetric String (25) 动态规划
- 欢迎使用CSDN-markdown编辑器
- 自定义view,实现listview效果优化内存
- 90行python搭一个音乐搜索工具 —— Song Finder
- DDR3的理
- Linux下关闭开启防火墙
- Xamarin.Android开发实践(九)
- Android BLE开发之Android手机与BLE终端通信