「贪心」诸葛的理想

本题为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;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

posted @ 2023-01-09 15:18  星双子  阅读(12)  评论(0编辑  收藏  举报