「贪心」诸葛的理想
本题为1月6日22寒假集训每日一题题解
题目来源:(未知)
题面
题目描述
人人都有理想,诸葛也不例外。
诸葛有很多理想,但是诸葛没有那么多的精力去实现那么多的理想,他想在有限的精力内实现最多的理想。
输入
每组数据第一行输入两个整数N,V,表示诸葛有N个理想,精力为V。
接下来N行中每行有一个整数X,表示实现这个理想要耗费的精力为X。
输出
输出诸葛最多能实现的理想数量。
样例输入
3 10
1
5
6
样例输出
2
提示
30%数据满足,N<=1000 X<=10000000
60%数据满足,N<=1000 X<= $ 2 ^ 31 - 1 $
100%数据满足,N<=100000 X<= $ 2 ^ 31 - 1 $ V <= $ 2 ^ 31 - 1 $
思路分析
本题第一眼看时,我以为是01背包问题
的变式题,但是再看这个并不利于使用动态规划
数据量,发现其实是一道使用贪心算法
的题目.
显然,想要在给定的精力限制中实现更多的理想,就需要每次选完一个理想后,剩下的精力限制更多,也即当前理想所消耗的精力越少,这样后续才能有可能选更多的理想.所以本题的贪心策略就是每次都实现精力消耗最小的那个理想.
代码实现起来很简单,只需要将各个精力值在数组中升序排序,然后遍历这个数组,不断消耗精力,直到限制的精力全部消耗完毕即可.
参考代码
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n, v;
cin >> n >> v;
int *a = new int[n]; // 各个梦想的精力值
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a, a + n); // 升序排序
// 遍历数组,不断消耗精力,直到消耗完毕
int res = 0;
while (v > 0)
{
v -= a[res++];
}
cout << res - (v < 0) << "\n"; // 如果当前v被剪成负数,那么最后一个梦想是不能实现的,要减掉
delete a;
a = nullptr;
return 0;
}
"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德
这里是浙江理工大学22届ACM集训队的成员一枚鸭!
本文首发于博客园,作者:星双子,除了我自己的转载请注明原文链接:https://www.cnblogs.com/geministar/p/zstu22_1_6.html