您的位置:首页 > 其它

Sicily 2015 A New Year Gift

2014-11-24 21:37 253 查看
一开始的想法是直接模拟,但是提交之后发现会超时。参考了各位大神的思路,采用二分逼近查找。最终的种类数量肯定在最低值0与最高值sum/m(总珍珠数/组数)之间。每次去中间值进行逼近,知道bot > top为止。采用贪心算法,不用考虑具体实现,每次只要取种类数和每种的个数中的较小值即可。最终对二分逼近的值进行判断,若能组成则输出,否则减一输出

// Problem#: 2015
// Submission#: 3269318
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main() {
int m, n;
int top, bot, mid;
int a[1005];
int sum = 0;
while (scanf("%d", &n) && n) {
sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
sum += a[i];
}
scanf("%d", &m);

bot = 0;  //  低值
top = sum / m;  //  高值
while (bot < top) {  //  判断终止条件
mid = (bot + top) / 2;  // 二分中值逼近
sum = 0;
for (int i = 0; i < n; i++) {
sum += min(mid, a[i]);
}
sum >= mid * m ? bot = mid + 1: top = mid - 1;  //  改变bot 或top
}
sum = 0;
for (int i = 0; i < n; i++) {  //  判断是否可以组成二分逼近的结果
sum += min(bot, a[i]);
}
printf("%d\n", sum >= bot * m ? bot : bot - 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: