题目出处:洛谷 P2676,不过题目描述改掉了,程序也稍有不同。
题目描述
茜茜和聪聪是关系很好的同桌,有一天,茜茜觉得天空中的白云像棉花糖一样,应该很好吃吧,但是够不着,她很烦恼。
聪聪为了帮助茜茜解决烦恼,决定帮他把天空中的白云摘下来做成棉花糖给她吃。
但是聪聪也够不着。于是他购买了 \(n\) 个AI3403型超级机器人来帮助他摘天空中的白云。
这些机器人可以采取叠罗汉的方式第在一起,叠在一起的高度就是这些机器人的身高之和,并且如果最高的那个自己人的身高达到白云的高度,他们就可以摘到白云来制作棉花糖了。
但是有一个问题是:虽然这些机器人都是同一个型号的,但是制作它们的灵灵博士在设计的时候为了展现机器人的多样性所以为每一个机器人设计了不同的身高,第 \(i\) 个机器人的升高被设计成了 \(h_i\) 。
显然,叠成的罗汉中机器人的数量越多,这个罗汉就越不稳定。所以聪聪希望在能够到白云的前提下,让罗汉中机器人的数量尽可能的少。请你帮助聪聪计算所需机器人的最小的数量。
输入格式
输入的第一行包含两个正数 \(n(1 \le n \le 10000)\) 和 \(b(1 \le b \le 10^9)\) ,分别表示聪聪购买的机器人的数量和白云的高度。
接下来 \(n\) 行每行包含一个整数 \(h_i(1 \le hi \le 10^5)\) ,用于表示第i个机器人的身高。
输出格式
输出一个整数,用于表示最少需要多少机器人才能够够着白云;如果所有的机器人叠在一起都够不着白云,则输出“-1”。
样例输入
6 40 6 18 11 13 19 11
样例输出
3
问题分析
这道题目比较简单,只需要从高到低来挑选机器人就可以了。
所以我们首先需要对这些机器人从高到低排序,然后从高到低选出前面 \(k\) 个人,并且这 \(k\) 个人的身高之和 \(\le b\) ,那么我们就找到了机器人的最少数量 \(k\) 。这本质上属于“贪心”算法的思想——我每一次选都要让我下一轮选的机器人数量尽可能的少,那么我每次选都去选择最高的那个机器人。
实现代码如下:
#include <bits/stdc++.h> using namespace std; const int maxn = 20020; int n, h[maxn]; long long B, tmp; bool cmp(int a, int b) { return a > b; } int main() { cin >> n >> B; for (int i = 0; i < n; i ++) cin >> h[i]; sort(h, h+n, cmp); for (int i = 0; i < n; i ++) { tmp += h[i]; if (tmp >= B) { cout << i+1 << endl; return 0; } } cout << -1 << endl; return 0; }
其中,变量tmp表示我目前叠罗汉的高度。
然后每次循环第i个机器人的时候,我就将 \(tmp += h[i]\) ,此时只要 \(tmp \ge h[i]\) ,就说明我叠罗汉的高度已经可以摘白云了,此时就可以输出 \(i+1\) 作为我的答案了(因为数组坐标是从 \(0\) 开始的)。而如果 \(n\) 个机器人叠上去之后还没有够着白云,则再循环结束都没有 return,则输出“-1”。