超级项链
Time Limit : 20000/10000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 80 Accepted Submission(s) : 22
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
笨笨是一个很笨的人,但即使这样他还是追到了全校最美的校花。但是最近出现一个高富帅来挖墙脚,笨笨倍感压力,眼看着校花女友要落入他人手中,笨笨怎能坐以待毙,于是笨笨打算为校花女友做一个超级项链来逆袭高富帅。
经高人指点,笨笨在一个神秘的山洞里发现n个价值连城的宝石。每个宝石都有一个价值Vi和质量Wi。笨笨不是一个贪心的人,他只想从中拿出k个宝石来做项链,以便把其余的留给下一个和他有相似经历的人,从n个宝石中选出k个有很多方案,但是笨笨只想得到最具性价比的方案(即单位质量的价值最大),面对这一问题,笨笨想了好久也没有结果,想请你来帮助他,笨笨的幸福就掌握在了你的手中啊~。
经高人指点,笨笨在一个神秘的山洞里发现n个价值连城的宝石。每个宝石都有一个价值Vi和质量Wi。笨笨不是一个贪心的人,他只想从中拿出k个宝石来做项链,以便把其余的留给下一个和他有相似经历的人,从n个宝石中选出k个有很多方案,但是笨笨只想得到最具性价比的方案(即单位质量的价值最大),面对这一问题,笨笨想了好久也没有结果,想请你来帮助他,笨笨的幸福就掌握在了你的手中啊~。
Input
测试样例有多组,每组测试样例之间有一个空行,处理到EOF。
每组测试样例第一行是n,k (0<=k<=n<=10000)。
接下来有n行,每行输入Vi和Wi (0<=Vi<=100000,0<Wi<=100000)。
所有输入数据都是整数。
每组测试样例第一行是n,k (0<=k<=n<=10000)。
接下来有n行,每行输入Vi和Wi (0<=Vi<=100000,0<Wi<=100000)。
所有输入数据都是整数。
Output
每组数据输出一行,即单位质量的最大价值。
结果保留2位小数。
k为0时,请输出0.00
结果保留2位小数。
k为0时,请输出0.00
Sample Input
3 1 3 3 3 4 3 2
Sample Output
1.50
#define DeBUG #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <string> #include <set> #include <sstream> #include <map> #include <bitset> using namespace std ; #define zero {0} #define INF 0x3f3f3f3f #define EPS 1e-5 typedef long long LL; const double PI = acos(-1.0); //#pragma comment(linker, "/STACK:102400000,102400000") inline int sgn(double x) { return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1); } #define N 10005 double v[N], w[N]; double p[N]; double maxx; int n, k; /** * ans=sum(xi*vi)/sum(xi*wi) * sum(xi*vi)-ans*sum(xi*wi)=0; * sum(xi*(vi-ans*wi))=0 * 单调递减 */ bool ju(double ans) { for (int i = 0; i < n; i++) { p[i] = v[i] - ans * w[i]; } sort(p, p + n); double sum = 0; for (int i = n - 1, j = 0; i >= 0 && j < k; j++, i--)//排序后选前k个 { sum += p[i]; } return sum >= 0; } int main() { #ifdef DeBUGs freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin); #endif while (scanf("%d%d", &n, &k) + 1) { maxx = 0; for (int i = 0; i < n; i++) { scanf("%lf%lf", &v[i], &w[i]); maxx = max(maxx, v[i] / w[i]); } if (k == 0) { printf("0.00\n"); continue; } double l, r, mid; l = 0; r = maxx; while (r - l > EPS)//注意控制精度 { mid = (l + r) / 2; if (ju(mid)) l = mid; else r = mid; } printf("%.2lf\n", l); } return 0; }