POJ 2976 3111(二分-最大化平均值)

POJ 2976

题意

给n组数据ai,bi,定义累计平均值为:

现给出一个整数k,要求从这n个数中去掉k个数后,最大累计平均值能有多大?(四舍五入到整数)

思路

取n?k个数,使得累计平均值最大。

定义C(x)表示能否取得n?k个数,使得累计平均值≥x。然后二分搜索最大的x。

可以这样判断可行性:

只需要从大到小选取n?k个(100?ai?x?bi)并求和sum,根据sum≥0来判断(上述的S表示n?k个元素下标的集合)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
int n, k;
ll a[1000 + 4], b[1000 + 4];
double c[1000 + 4];
bool C(double x) { // 检验取出的n-k个数的累计平均值是否能>=x
	for (int i = 0; i < n; ++i)    c[i] = a[i] * 100 - x*b[i];
	sort(c, c + n);
	double sum = 0;
	for (int i = 0; i < n - k; ++i) sum += c[n - i - 1];
	return sum >= 0;
}
void solve() {
	double lb = 0, ub = 1000000000000000.0;
	for (int i = 0; i < 100; ++i) { // 精度10e-30
		double mid = (ub + lb) / 2.0;
		if (C(mid)) lb = mid; // 半闭半开区间[lb, ub)
		else ub = mid;
	}
	printf("%.f\n", floor(lb + 0.5)); // 四舍五入
}
int main()
{
	while (cin >> n >> k) {
		if (n == k && n == 0) break;
		for (int i = 0; i < n; ++i) cin >> a[i];
		for (int i = 0; i < n; ++i) cin >> b[i];
		solve();
	}
	return 0;
}

POJ 3111

题意

给出n个珠宝的vi和wi,从中选出k个珠宝,使得最大,求出这k个珠宝的序列。

思路

同上,排序时需记录序号。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const double EPS = 1e-6;
int n, k;
int v[100000 + 5], w[100000 + 5];
struct Remian{
	double c;
	int id;
	bool operator<(const Remian&b) const {
		return c > b.c;
	}
} remain[100000 + 5];
bool C(double x) {
	for (int i = 0; i < n; ++i) {
		remain[i].c = v[i] - w[i] * x;
		remain[i].id = i + 1; // 记录宝珠编号
	}
	sort(remain, remain + n);
	double sum = 0.0;
	for (int i = 0; i<k; ++i) sum += remain[i].c;
	return sum >= 0;
}
void solve() {
	double lb = 0.0, ub = 1000000000000000.0;
	//while (ub - lb > EPS) { // 精度1e-6
	for(int i=0; i<80; ++i) { // 精度10e-30
		double mid = (lb + ub) / 2.0;
		if (C(mid)) lb = mid; // 半闭半开区间[lb, ub)
		else ub = mid;
	}
	for (int i = 0; i < k; ++i) printf(i == 0 ? "%d" : " %d", remain[i].id);
	printf("\n");
}
int main()
{
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; ++i) scanf("%d%d", &v[i], &w[i]);
	solve();
	return 0;
}
时间: 2024-10-29 19:08:08

POJ 2976 3111(二分-最大化平均值)的相关文章

POJ 3111 K Best 二分 最大化平均值

1.题意:给一共N个物品,每个物品有重量W,价值V,要你选出K个出来,使得他们的平均单位重量的价值最高 2.分析:题意为最大化平均值问题,由于每个物品的重量不同所以无法直接按单位价值贪心,但是目标值有界且能判断与最后答案的大小关系,所以用二分来做 3.代码: 1 # include <iostream> 2 # include <cstdio> 3 # include <cmath> 4 # include <algorithm> 5 using names

poj 3111 K Best 最大化平均值 二分思想

poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件C(x):=可以选择使得单位重量的价值不小于x 如何判定C(x)是否可行 假设选了某个物品的集合是S,那么单位重量的价值是:\[ \sum\limits_{i \in S} {v_i } /\sum\limits_{i \in S} {w_i } \] 因此就变成了判断是否存在S满足下面的条件:\[

POJ 3111 K Best &amp;&amp;NYOJ 914 (二分+ 贪心,最大化平均值)

链接:NYOJ:click here, POJ:click here 题意:(最大化平均值,挑战编程P143) 有n个物品的重量和价值分别是w[i]和v[i],从中选出K个物品使得单位重量的价值最大.(1<=k<=n<=10^41<=w[i],v[i]<=10^6) 一般想到的是按单位价值对物品排序,然后贪心选取,但是这个方法是错误的,比如对nyoj的例题来说,从大到小地进行选取,输入的结果是5/7=0.714对于有样例不满足.我们一般用二分搜索来做(其实这就是一个01分数规

POJ 3111 K Best(最大化平均值)

题目链接:click here~~ [题目大意]有n个物品的重量和价值分别是Wi和Vi,从中选出K个物品使得单位重量的价值最大,输出物品的编号 [解题思路]:最大化平均值的经典.参见click here~~ 代码: //#include <bits/stdc++.h> #include <stdio.h> #include <math.h> #include <string.h> #include <iostream> #include <

二分算法的应用——最大化平均值

最大化平均值 有n个物品的重量和价值分别wi 和 vi.从中选出 k 个物品使得 单位重量 的价值最大. 限制条件: 1 <= k <= n <= 10^4 1 <= w_i <= v_i <= 10^6 输入:n = 3k = 2{W, V} = {(2,2), (5,3), (2,1)} 输出:0.75 (如果选0号和2号,平均价格是 (2 + 1) / (2 + 2) = 0.75) 题解: 一般先想到的肯定是:把物品按照  单位价值  进行排序,然后从大到小贪心

【二分查找-最大化平均值】POJ2976 - Dropping Test

[题目大意] 给出n组ai和bi,去掉k个使得a的总和除以b的总和最大. [思路] 也就是取(n-k)个数,最大化平均值,见<挑战程序设计竞赛>P144,最后公式为c(x)=((ai-x*bi)从大到小排列的前(n-k)个的和不小于0) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath>

二分法 最大化平均值

摘自 挑战程序设计竞赛 和最大化最小值类似,最大化平均值也可以通过二分法求得. 比如下面这个经典的问题: 有n个物品的重量和价值分别是wi和vi,从中选出k个物品使得单位重量价值最大. 样例输入: 3 22 25 32 11234样例输出: 0.751分析: 一般先想到的是将每个物品的单位重量价值算出来,然后排个序,从大到小贪心进行选择,可惜这样是不对的,这样不能保证最后一定是最大平均值,直接用贪心对于这类要涉及多个因素比如求最大平均值的问题就显得不那么正确了. 那么我们这样分析这个问题: 令C

POJ 3484 Showstopper 二分

 Showstopper Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1218   Accepted: 356 Description Data-mining huge data sets can be a painful and long lasting process if we are not aware of tiny patterns existing within those data sets. On

poj 1469 COURSES (二分匹配)

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16877   Accepted: 6627 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss