Uva 714 (抄书问题,二分查找+贪心)
2017-11-10 15:31
387 查看
题目链接在
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=655
这题要求最大值尽量小,最大值越小肯定越难,所以如果最大值可以是x1的话, 那么x2>x1肯定也可以,所以这里可以用binary search。
另外还要加greedy search,从最右边开始(因为题目规定S(1) 尽量小, 若S(1)一样则S(2)尽量小…),尽量把多的数放到一起(只要sum不大于目标值即可)。
代码如下:
设所有n个元素的SUM和为M, 二分次数为logM,每次整个数组都扫一遍。所以复杂度为O(nlogM)。
这题要注意跟sum有关的变量都用long long,不然可能溢出。我在Uva上提交的结果是Presentation Error。应该是结果对,但输出不符合要求。不知道具体什么原因,以后再查,欢迎有知道原因的同学留言。也欢迎大家对我的代码提出改进意见。
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=655
这题要求最大值尽量小,最大值越小肯定越难,所以如果最大值可以是x1的话, 那么x2>x1肯定也可以,所以这里可以用binary search。
另外还要加greedy search,从最右边开始(因为题目规定S(1) 尽量小, 若S(1)一样则S(2)尽量小…),尽量把多的数放到一起(只要sum不大于目标值即可)。
代码如下:
#include <iostream> #include <vector> #include <algorithm> using namespace std; vector<int> ans; //test if we can divide the data array into x parts, with the max of the sum in each part not larger than x bool P(vector<int>&data, int k, long long x) { int p1 = data.size()-1; long long tempSum = 0; ans.resize(0); while (p1 >= 0) { while ((tempSum <= x) && (p1>=k-2)) { tempSum += data[p1--]; } p1++; //bounce back because p1 moves too much. ans.push_back(p1); k--; if (p1<k-1) { return false; } tempSum = 0; if (k==1) { long long sum1 = 0; for (int i=0; i<=p1; i++) { sum1 += data[i]; } if (sum1 <= x) { return true; } else { return false; } } } } int main() { int n,k,T; vector<int> data; cin>>T; while(T--) { long long sum = 0; int maxi = 0; cin>>n>>k; data.resize(n); for (int i=0; i<n; i++){ cin>>data[i]; sum+=data[i]; maxi=max(maxi, data[i]); } if (k==1) { for (vector<int>::iterator it = data.begin(); it<data.end(); it++) cout<<*it<<" "; cout<<endl; continue; } //binary search with P(x) long long l = 0; long long r = sum; while (l<r) { long long m = l + (r-l)/2; if (P(data, k, m)) { r = m; //the answer is less than or equal to m } else { l = m+1; //the answer should be larger than m } } P(data, k, l); vector<int>::reverse_iterator r_it = ans.rbegin(); for (int i=0; i<data.size(); i++) { cout<<data[i]<<" "; if (i==*r_it) { cout<<"/ "; ++r_it; } cout<<endl; } } return 0; }
设所有n个元素的SUM和为M, 二分次数为logM,每次整个数组都扫一遍。所以复杂度为O(nlogM)。
这题要注意跟sum有关的变量都用long long,不然可能溢出。我在Uva上提交的结果是Presentation Error。应该是结果对,但输出不符合要求。不知道具体什么原因,以后再查,欢迎有知道原因的同学留言。也欢迎大家对我的代码提出改进意见。
相关文章推荐
- UVA 714 Copying Books 最大值最小化问题 (贪心 + 二分)
- UVA 714 Copying Books 最大值最小化问题 (贪心 + 二分)
- UVa 714 抄书(贪心+二分)
- UVa 714 Copying Books 二分 + 贪心 (最大值最小化问题)
- POJ-1505&&UVA-714 抄书(贪心+二分)
- UVa 714 - Copying Books(二分查找)
- UVa 714 Copying Books (最大值尽量小_二分+贪心)
- uva 714 - Copying Books(二分+贪心)
- UVa 714 抄书 二分答案
- uva--714+二分(最大值最小化问题)
- 714 - Copying Books——[贪心、二分查找]
- UVA - 714 Copying Books(二分+贪心)
- uva 714 - Copying Books(贪心 最大值最小化 二分)
- UVA - 1152 4 Values whose Sum is 0问题分解,二分查找
- 二分,贪心(Copying Books,uva 714)
- UVA 714 Copying Books 抄书 (二分)
- 算法基础之python实现贪心算法中圣诞老人分糖果问题和二分查找算法中烘干衣服问题
- Uva 714 最大值最小化 (贪心+二分)
- 【二分答案+贪心】解决“最小值最大”问题(UVa 12124 - Assemble)
- UVA 714 Copying Books(二分+贪心)