codeforce 一道贪心题

原题目: http://codeforces.com/contest/68/problem/B

题意: 给出N个能量值a1, a2...an, 能量之间能互相转换, 但转换时会有k百分比的损失, 要求出最后各能量值相等时的最大值.

解题思路: 设最后达到平衡时能量值为 x, 则在转换时总共损失了能量 (1式)(a1 + a2 +...+ an ) - N * x . 对于每一个a值,如果 a > x, 那么它必须要转换 a - x 单位能量, 之间损失 (a - x) * (k / 100), 问题是我们如何知道 ai 是否大于 x 呢? 这是问题所在也是解题的关键.我们可以从反面来进行贪心, 将N个ai值按从大到小的顺序排序, 假设前面 c 个a值都大如 x ,那么损失值为(2式) (a1 + a2 +...+ ac) - c * x, (1式)与(2式)建立相等关系, 可以求出一个 x 值, 用 x 与 a[c + 1], 作对比,如果 x 还小于 a[c + 1], 那么还可以继续进行贪心,直到大于.

1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <algorithm>
6 #include <vector>
7 #include <map>
8
9  using namespace std;
10
11  const int MAX = 10000 + 1;
12  bool comp(const double &a, const double &b)
13 {
14 return a > b;
15 }
16 int main()
17 {
18 //freopen("in.txt","r",stdin);
19 int n;
20 double k;
21 double energy[MAX];
22 double energySum = 0;
23 scanf("%d%lf", &n, &k);
24 for(int i = 0; i < n; ++i)
25 {
26 scanf("%lf", &energy[i]);
27 energySum += energy[i];
28 }
29 sort(energy, energy + n, comp);
30 k /= 100;
31 double sum = 0;
32 double ans = 0;
33 energy[n] = 0;
34 for(int i = 0; i < n; ++i)
35 {
36 sum += energy[i];
37 ans = (k * sum - energySum) / ((i + 1) * k - n);
38 if(ans >= energy[i + 1])
39 {
40 break;
41 }
42 }
43 printf("%.9lf\n", ans);
44 return 0;
45 }
posted on 2011-03-19 11:39  Kenfly  阅读(565)  评论(0编辑  收藏  举报