工作安排价值最大、判断凸边形、二叉树的括号表示法
//选择工作安排使得收益最大化问题
/
类似 任务调度的题 ,例如 P2949 [USACO09OPEN]Work Scheduling G
首先所有项目按照时间排序,使用堆(优先队列)管理已选的项目,把获利最小的项目放在堆顶,然后如果已选的项目数量
(也可以当作已经消耗的时间)和当前比较的项目的时间更短,证明可以直接选择项目(加入堆),否则判断当前项目和堆顶
项目谁的获利更大,更大的就加入其中。
/
struct Job {int t;int w;Job(int tt, int tw) : t(tt), w(tw) {};bool operator<(const Job& other) const {//小顶堆return w > other.w;}};bool t_cmp(const Job& g1, const Job& g2) {return g1.t < g2.t;// 按ddl排序}LL max_value_Jobs(const vector<Job>& all) {LL ret = 0;priority_queue<Job> take;for(int i = 0; i < all.size(); i++) {if(all[i].t <= take.size()) {if(take.top().w < all[i].w) {ret = ret - take.top().w * 2 + all[i].w;//这里不选择是减分,所以是减去双倍的分值take.pop();take.push(all[i]);}} else {ret += all[i].w;take.push(all[i]);}}return ret;}
/ 判断是不是一个凸多边形
tip: 对于边AB BC 如果C在边的同一侧 则这个点满足凸多边形,即沿着边绕多边形一圈,总是往一个方向拐弯的是多边形。
/
struct Point {double x, y;Point(double tx, double ty) : x(tx), y(ty) {};};double get_side(Point* p1, Point* p2, Point* p3) {double x1, x2, y1, y2;x1 = p3->x - p1->x;x2 = p2->x - p1->x;y1 = p3->y - p1->y;y2 = p2->y - p1->y;return (x1 * y2 - x2 * y1);}bool is_porly(const vector<Point*>& ps) {for(int i = 0; i < ps.size(); i++) {double res = 0;int count = 0;Point* pi = ps[i], *pj;int j;if(i == ps.size() - 1) {pj = ps[0];j = 0;} else {pj = ps[i + 1];j = i + 1;}for(int k = 0; k < ps.size(); k++) {if(k == i || k == j) continue;Point* pk = ps[k];double side = get_side(pi, pj, pk);if(count == 0) {res = side;} else if(res * side < 0) {return false;}count++;}}return true;}
//给一个由先序遍历序列化的 二叉树(字符串),由它反序列重建二叉树,比如“A(B(D,),C(,E))”
/
主要思路是 ‘( ‘ 前面的就是根节点,之后的话,使用栈来处理’(’ ‘)’符号,当栈里面只有一个 ‘(’ 并且当前字符是 ‘ ,’,
就可以拆分成左右两个子树,然后递归处理即可,记得处理好叶子节点的情况,叶子节点没有’(‘和’)’
/
TreeNode* rebuildTree(const string& s, int left, int right){
if(left>right) return nullptr;
stack<char> stk;
string val;
while(left<=right&&s[left]!='('){
val+=s[left];left++;
}
TreeNode* root=new TreeNode(val);
for(int i=left;i<=right;++i){
if(s[i]=='('){
stk.push(s[i]);
}else if(s[i]==')'&&stk.size()>1){
stk.pop();
}else if(s[i]==','&&stk.size()==1){
root->left=rebuildTree(s,left+1,i-1);
root->right=rebuildTree(s,i+1,right-1);
}
}
return root;
}
