分析:我们采用贪心做法,优先吃过期时间早的。
证明:考虑贪心解和最优解
如果最优解和贪心解不一样,找到第一天不同的点进行比对。
假设贪心解第\(k\)天吃的是\(a_{i}\)苹果,\(k + 1\)天吃的是\(a_{j}\)苹果,而最优解第\(k\)天吃的是\(a_{j}\)苹果,第\(k + 1\)天吃的是\(a_{i}\)苹果。

把最优解第\(k\)天吃的苹果换成\(a_{i}\),只要证明出来方案不会变差,说明贪心解也是一个最优解。
由于贪心解优先吃过期时间早的,那么\(t_{i} <= t_{j}\)

分情况讨论:
情况1:如果最优解中\(a_{i}\)\(a_{j}\)都有吃,在最优解里面是先吃\(a_{j}\),再吃\(a_{i}\)\(t_{i} <= t_{j}\),交换成贪心解,查看是否会过期,
第一天,先吃\(a_{i}\),由于交换前的最优解里面后吃\(a_{i}\)没有过期,那么提前时间吃,贪心解肯定也不会过期,第二天,吃\(a_{j}\)
由于交换前吃\(a_{i}\)不会过期,且\(a_{i}\)的过期时间早于\(a_{j}\),那么换成\(a_{j}\)也不会过期。因此,贪心解得到的结果不会变差,贪心解也是一个最优解。

情况2:在最优解里面,只吃了\(a_{j}\),没有吃\(a_{i}\),交换,先吃过期时间为\(t_{i}\)的苹果,\(t_{j}\)是在\(t_{i}\)后面过期的,因为交换前吃\(a_{j}\)没有过期,那么交换后吃\(a_{i}\)
因为贪心解里面吃\(a_{i}\)没有过期,那么提前吃\(a_{i}\),在最优解里面也不会过期。

class Solution {
public:
    int eatenApples(vector<int>& apples, vector<int>& days) {
        typedef pair<int, int> pii;
        priority_queue<pii, vector<pii>, greater<pii>> heap;

        int res = 0;
        int n = apples.size();

        for(int i = 0; i <= 40000; ++i)
        {
            //只将个数大于0的苹果加入到优先队列
            if(i < n && apples[i] > 0)
            {
                heap.push({i + days[i] - 1, apples[i]});
            }
            //将过期的苹果弹出优先队列
            while(heap.size() && heap.top().first < i) heap.pop();
            if(heap.empty()) continue;
            ++res;
            //存在过期时间大于当前时间的苹果
            auto t = heap.top();
            heap.pop();
            if(--t.second > 0)
                heap.push(t);
        }
        return res;
    }
};