【LittleXi】Plan a part-time job
Mental journey:
I got up in the morning and opened the topic, I didn’t have any ideas. I
clicked on “Dyson Ball” and it was noon. I quit the game, glanced at the line segment tree, and it took a second.
Summary: Playing games can also improve thinking ability
problem solving ideas
Line segment tree + discretization + dp
discretization: because the time is too long (1e9), we should sort the time, and use the order 1, 2, 3 to simulate the time order
dp: sort the line segments by the first node, for each The maximum profit of a node can be transferred from the maximum profit of all previous nodes, that is, nowprofit=the maximum profit of all previous nodes+profit[now] Line segment
tree: When looking for the maximum profit before, we can think of using the line segment tree to find the interval Maximum
Time Complexity: O(nlogn)
the code
#define lc k<<1
#define rc k<<1|1
const int maxn = 500010;
const int inf = 0x3f3f3f3f;
int n, a[maxn];
struct node
{
int l, r, mx;
};
node tree[maxn * 4];
void build(int k, int l, int r)//创建叶子节点,k表示存储下标,l,r表示更新区间
{
tree[k].l = l;
tree[k].r = r;
if (l == r)
{
tree[k].mx = a[l];
return;
}
int mid = (l + r) / 2;
build(lc, l, mid);
build(rc, mid + 1, r);
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
void update(int k, int i, int v)//点更新,将a[i]修改为v
{
if (tree[k].l == tree[k].r && tree[k].l == i)
{
tree[k].mx = v;
return;
}
int mid = (tree[k].l + tree[k].r) / 2;
if (i <= mid)
update(lc, i, v);
else
update(rc, i, v);
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
int query(int k, int l, int r)//区间覆盖查询,求区间[l,r]的最大值
{
if (tree[k].l >= l && tree[k].r <= r)
return tree[k].mx;
int mid = (tree[k].l + tree[k].r) / 2;
int ma = -inf;
if (l <= mid)
ma = max(ma, query(lc, l, r));
if (r > mid)
ma = max(ma, query(rc, l, r));
return ma;
}
class Solution {
public:
int jobScheduling(vector<int>& st, vector<int>& en, vector<int>& pr) {
int n = st.size();
vector<vector<int>> vec(n);
set<int> lisan;
for (int i = 0; i < n; i++)
{
lisan.insert(st[i]);
lisan.insert(en[i]);
}
int p = 1;
unordered_map<int, int> m;
for (auto& val:lisan)
{
m[val] = p++;
}
for (int i = 0; i < n; i++)
{
vec[i].push_back(m[st[i]]);
vec[i].push_back(m[en[i]]);
vec[i].push_back(pr[i]);
}
sort(vec.begin(), vec.end(), [&](vector<int>& v1,
vector<int>& v2) {
return v1[0] < v2[0]; });
memset(a, 0, sizeof(a));
build(1, 0, 500005);
for (int i = 0; i < n; i++)
{
int be = vec[i][0];
int en = vec[i][1];
int money = vec[i][2];
int temp = query(1, 1, be);
a[en] = max(a[en],temp + money);
update(1, en, a[en]);
}
int re = *max_element(a, a + 500000);
return re;
}
};