解题报告 之 HDU5303 Delicious Apples
2017-07-20 13:33
148 查看
解题报告 之 HDU5303 Delicious Apples
DescriptionThere 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?
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
题目大意:一个给定长度为L的圈。你在0位置。
圈上有n个苹果树(给出位置),每棵树下有一定数量的苹果。你有一个能装K个苹果的框子。如今你要将全部苹果运到你所在的位置。问你最少走多少路?
分析:第一点非常easy想到,离起点左右非常近的苹果更倾向于选择原路返回更省。而靠近中间的苹果有可能打包绕一圈再回来更省。
那么问题来了?这个“中间”究竟如何才算中间呢,这个点就是这个题的精髓。
大家能够把这个中间想成一个区间,问题的难点就转化为了怎么选择这个区间。也就是我们要决定选择哪些苹果绕一圈打包回来更省。
这的确是一个难解决的问题。。也是本题巧妙的地方。我们枚举究竟要把那些苹果绕一圈打包带回。我们把一个一个苹果离散出来而不再以苹果树作为考虑对象。并把这些苹果划分为更靠近左边和更靠近右边的。那么我们要枚举的就是,要从左边拿多少个(无疑是最远的那几个)到绕一圈的这个框中。
注意重点在于,从左边最多取K个,也就是仅仅有最后一筐可能须要绕一圈。由于假设从左边取超过K个。那么我们全然能够先取K个依照原路返回的方法(路程一定<=L),那之后问题终于回归不超过K个。
我们枚举的实质事实上在尝试一种平衡局面,使得左右两边选择原路返回路线的框能够尽量利用充分,而不要出现有一趟原路返回仅仅装1、2个苹果。
上代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<cstring> using namespace std; typedef long long ll; const int MAXN = 1e5 + 10; ll loc[MAXN]; ll disl[MAXN], disr[MAXN];//依照原路返回策略取完第i个苹果所走的路程 ll ans, L, n, k, cnt; vector<ll> lloc, rloc; //存储从左右数的苹果位置 int main() { int kase; scanf( "%d", &kase ); while(kase--) { memset( disl, 0, sizeof disl ); memset( disr, 0, sizeof disr ); lloc.clear(); rloc.clear(); cnt = 0; scanf( "%lld%lld%lld", &L, &n, &k ); for(int i = 1; i <= n; i++) { ll location, number; scanf( "%lld%lld", &location, &number ); for(int j = 1; j <= number; j++) //离散化 loc[cnt++] = location; } for(int i = 0; i < cnt; i++) { if(2 * loc[i] < L) lloc.push_back( loc[i] ); else rloc.push_back( L - loc[i] ); }//苹果分边 sort( lloc.begin(), lloc.end() ); sort( rloc.begin(), rloc.end() ); int left = lloc.size(), right = rloc.size(); for(int i = 0; i < left; i++) disl[i + 1] = (i + 1 <= k ? lloc[i] : disl[i + 1 - k] + lloc[i]); for(int i = 0; i < right; i++) disr[i + 1] = (i + 1 <= k ? rloc[i] : disr[i + 1 - k] + rloc[i]); ans = (disl[left] + disr[right]) * 2; //不绕一圈的情况,不要忘了 for(int i = 0; i <= left&&i <= k; i++)//枚举绕一圈的那框从左边取多少 { ll pickl = left - i; ll pickr = right - (k - i); ans = min( ans, 2 * (disl[pickl] + disr[pickr]) + L ); } printf( "%lld\n", ans ); } return 0; }
相关文章推荐
- 解题报告 之 HDU5303 Delicious Apples
- 楼教主男人必解八题之 Coins 解题报告
- Two Sum | LeetCode OJ 解题报告
- [leetcode] 308. Range Sum Query 2D - Mutable 解题报告
- UVA 12535 Probability Through Experiments 解题报告
- Allocation of Memory 解题报告
- 洛谷10月21日模拟赛解题报告
- pku acm 2248 addtion chians 解题报告
- POJ_2002Squares解题报告
- POJ 1845 Sumdiv 解题报告(二分 & 逆元)
- 第12届浙江省大学生程序设计大赛 解题报告
- 12月份大一周赛解题报告
- 解题报告 之 POJ1637 Sightseeing tour
- [bzoj4025]二分图 解题报告
- 【解题报告】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)
- poj 1007 DNA Sorting 解题报告
- 【LeetCode】Combinations 解题报告
- 重庆市队选拔 CQOI2015 解题报告
- BestCoder Round #77 (div.2)解题报告
- POJ - 1837 Balance解题报告