公司最近研发了一种产品,共生产了n件。有m个客户想购买此产品,第i个客户出价Vi元。为了确保公平,公司决定要以一个固定的价格出售产品。
每一个出价不低于要价的客户都将会以公司决定的要价购买一件产品,余下的将会拒绝购买。找出能使公司利润最大化的最小售价。
输入:
第一行两个整数n(1<=n<=1000),m(1<=m<=1000),分别表示产品数和客户数
接下来第二行m个整数Vi(1<=Vi<=100000),分别表示第i个客户的出价
输出:
每一个出价不低于要价的客户都将会以公司决定的要价购买一件产品,余下的将会拒绝购买。找出能使公司利润最大化的最小售价。
输入:
第一行两个整数n(1<=n<=1000),m(1<=m<=1000),分别表示产品数和客户数
接下来第二行m个整数Vi(1<=Vi<=100000),分别表示第i个客户的出价
输出:
输出一行整数,代表能够让公司利润最大化的最小售价
样例输入:
5 4
2 8 10 7
样例输出:
7
分析:
要价越大越好?要价越大单个产品利润越大,但买得起的都是土豪,卖出的产品数会小;要价越小,虽然卖出的产品数为增加,但单个产品利润会减小。
因此要找到最小的要价x,使得出价>x的人数 * x最大
思想:
先将客户出价按从小到大排序,因为我们要找最小的要价,不知道客户的底线是不行的
对于出价 2 8 10 7,排序后得到2 7 8 10
现在枚举要价
有必要从1开始逐个枚举吗?
没有。例如,枚举一个介于2到7直接的要价x(2<x<7),买得起的有出7 8 10的三个人,销售总额= 3 * x;等到枚举到7时,买得起的仍是出7 8 10 的三个人,销售额 = 3 * 7 > 3 * x,所以对于客户要价之间的值进行枚举没有意义;
因此只需将要价按照客户出价从小到大进行枚举,
记出价数组为cj[0] cj[1] ... cj[i] cj[i+1] ... cj[m-1]
假设当前要价枚举到了cj[i],则出价不小于要价的有cj[i]到cj[m-1],总有m-i个人买得起,销售额=cj[i] * (m-i)
特殊情况:产品数少于买得起的用户数时,只能卖出产品数个产品
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; /*** * 公司最近研发了一种产品,共生产了n件。有m个客户想购买此产品,第i个客户出价Vi元。为了确保公平,公司决定要以一个固定的价格出售产品。 * 每一个出价不低于要价的客户都将会以公司决定的要价购买一件产品,余下的将会拒绝购买。找出能使公司利润最大化的最小售价。 * 输入: * 第一行两个整数n(1<=n<=1000),m(1<=m<=1000),分别表示产品数和客户数 * 接下来第二行m个整数Vi(1<=Vi<=100000),分别表示第i个客户的出价 * 输出: * 输出一行整数,代表能够让公司利润最大化的最小售价 * @author chenjie * */ public class 京东2017秋招5_拍卖产品 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String n_m = sc.nextLine(); int n = Integer.valueOf(n_m.split(" ")[0]); int m = Integer.valueOf(n_m.split(" ")[1]); List<Integer> V = new ArrayList<Integer>(m); String vi[] = sc.nextLine().split(" "); for(int i = 0; i < vi.length; i ++) { V.add(Integer.valueOf(vi[i])); } Collections.sort(V); int ans = 0, pos = 0; for(int i = 0; i < V.size(); i ++) { int num = n < V.size() - i ? n : V.size() - i; if(ans < V.get(i) * num) { ans = V.get(i) * num; pos = V.get(i); } } System.out.println(pos); sc.close(); } }