10.9课上

表达式求值(优先级方法)

用两个栈,一个栈用来存运算符,一个用来计操作数和运算结果

遇到操作数就进数栈,遇到操作符,根据操作符的优先级和运算符栈的栈顶元素比较,

如果栈顶大于等于,则不断从操作数里取俩数进行运算再放回去,直到优先级小于或只剩一个

如果栈顶小于,则直接入栈

特判如果相等且为终止符,则直接break

主持人调度复习

用一个队列,根据开始时间从小到大进行遍历,如果此时记录的数量都在工作,即此时的开始时间不大于已有的任何工作人的最早结束时间,那就需要一个新的人

否则,就是有大于最早的,那么就让最早结束的那个人来接手这个工作,即更新它记录的数,只更新它就够了,不需要再管其他可能已经结束的人,

但是需要让最早结束的人不断冒上来,所以是需要用小顶堆来实现的

最后的情况是堆里记录的数越来越大

堆的思想是这样,却也可以用数组来优化,就是用两个数组,一个是开始时间,一个是结束时间,都要排序,每个都有一个指针,主指针是开始时间,结束时间的指针指的是当前最早结束的人,如果早于现在的开始时间,就让它往后移,

反思

什么叫逻辑的第一个?

就是在原来的第一个的前面,如果插入了一个新元素,那么原来的第一就不是第一,那如果要遍历,是需要从逻辑上的第一个开始的,但”第一个“在不断更新,所以就需要一个绝对的变量来记录这个链表谁是第一个,并从其开始遍历

入栈时,或入队列时,数据结构中的元素和要新插入的元素需要满足某种关系,这才是模拟

取硬币

如果是深搜,两个参数,一个是当前的栈,一个是剩余次数

对每个栈都可以取或不取两种选择,

如果取的话,需要确定取多少,并确定取完后兜里的钱

不取直接下一个

递归终点是到最后一个栈,如果剩余次数为0,就和当前记录的最大值比一下

如果不为0,则不做操作return

记忆化一下就是走到这个栈时还有这么多取的次数时可以取的最大币值。

class Solution {
public:
    int maxValueOfCoins(vector> &piles, int k) {
        vector f(k + 1);
        int sumN = 0;
        for (auto &pile: piles) {
            int n = pile.size();
            for (int i = 1; i < n; ++i)
                pile[i] += pile[i - 1]; // pile 前缀和
            sumN = min(sumN + n, k); // 优化:j 从前 i 个栈的大小之和开始枚举(不超过 k)
            for (int j = sumN; j; --j)
                for (int w = 0; w < min(n, j); ++w)
                    f[j] = max(f[j], f[j - w - 1] + pile[w]); // w 从 0 开始,物品体积为 w+1
        }
        return f[k];
    }
};

 

 

你可能感兴趣的:(算法,c++,算法)