题解【J-Taxed Editor 】
P1 题目描述
P2 新学知识
除不尽的东西,想方设法转化为反过来的乘法也一个必要手段!!!记得可能要开longlong(详细展开就是,如果一组数据除了之后再和别人比较、加减,不如同乘)
P3 用到的模板
模板【二分】
P4 题目思路
这种任务分配问题,枚举每次的读书速度,每个任务的耗时会变,结束时间是不会变化的,所以只需要在开始排一下序就行,因为它的访问除了要求按照结束时间排序别无要求(感悟:对于逻辑关系应当理清楚,它要按A排序,A不变,就算B变,A也只需要排序一次;不过要区分开B每次变化是按照它原始的下标来的情况,这逻辑就变成了访问按照A排序,但每次更新B要按照原始id进行,故又要排序回去,而访问又要按A排序,所以简化操作:保留原始数据,直接在原始数据上操作-》这又引出了逻辑要素:在 什么数据(包括版本) 进行 什么操作)
P5 代码解析
#include<cstdio> #include<cmath> #include<algorithm> #include<set> #include<map> #include<cstring> #include<string> #include<vector> #include<queue> #include<iomanip> #include<iostream> #include<stack> using namespace std; ///-------------------------------------------------------常用规定部分 //----------------------通用 #define inf_ 0x3f3f3f3f//这是给int的inf,值为1061109567,2^31-1为2147483647 #define reg_ register int #define for_reg(i, n) for(int i = 1; i <= n; i++) #define ll_ long long #define ull_ unsigned long long //----------------------边访问 #define visit_edge int i = p[u]; ~i; i = e[i].next #define define_v int v = e[i].v #define define_v_avoid_f int v = e[i].v;if(v == fa) continue //----------------------线段树 #define mid_ int mid = (l+r)>>1//mid的定义 #define len_ (r-l+1) #define l_id id<<1 #define r_id id<<1|1 #define l_son id<<1,l,mid #define r_son id<<1|1,mid+1,r #define include_(x,y,l,r) x<=l && r<=y //----------------------其它 const int max_n = 1e5+10; const int max_m = 1e5+10; ///-------------------------------------------------------变量声明部分 //--------------------------------------其它 struct BOOK { ll_ page, endTime; bool operator < (const BOOK & tmp) const { return endTime < tmp.endTime; } } bookg[max_n]; struct TASK { ll_ costTime, endTime; } taskg[max_n]; ///--------------------------------------------------------函数声明部分 //--------------------------------------其它 priority_queue<ll_> choosedTask;//记录选中task的花费时间的最大值 bool Check(int targetNum, int n, ll_ speed) { //init ll_ costedTime = 0; int choosedNumber = 0; for_reg(i, n) { taskg[i].costTime = bookg[i].page; taskg[i].endTime = bookg[i].endTime*speed; if(costedTime+taskg[i].costTime <= taskg[i].endTime) { choosedNumber++; costedTime += taskg[i].costTime; choosedTask.push(taskg[i].costTime); } else if(choosedTask.size() && choosedTask.top() > taskg[i].costTime)//能换 { costedTime += taskg[i].costTime; costedTime -= choosedTask.top(); choosedTask.pop(); choosedTask.push(taskg[i].costTime); } } while(!choosedTask.empty()) choosedTask.pop(); if(choosedNumber >= targetNum) return true; else return false; } ///--------------------------------------------------------main函数部分 int main() { //freopen("in.txt","r", stdin); //freopen("out.txt","w", stdout); ios::sync_with_stdio(false); //InitEdge(); int n, m; cin >> n >> m; ll_ l = 1, r = 0; for(int i = 1; i <= n; i++) { cin >> bookg[i].page >> bookg[i].endTime; r += bookg[i].page; } sort(bookg+1, bookg+1+n); while(l < r) { ll_ mid = (l+r)/2; if(Check(n-m, n, mid)) { r = mid;//(找到最大值和这个是不一样的写法) } else { l = mid + 1; } } cout << l << endl; return 0; } ///--------------------------------------------------------函数定义部分 //----------------------------------其它
P6 奇怪的感悟们
over