• BZOJ1577: [Usaco2009 Feb]庙会捷运Fair Shuttle


    看上去并不可 dp,实际也不可 dp

    考虑线段树

    当前还能上车的数量可以用线段树维护

    考虑把区间按右端点排序,这样就可以贪心了

    并不会证明,感觉挺显然?

    大概就是你让早下车的上来了而不让晚下车的来
    这样可以让后边尽量上更多的

    大概这样就行了

    需要注意的是区间操作中都是 [l, r - 1]

    因为你可以让牛都先下车再上,
    这样相当于是和当前没有这些牛是一样的

    表示一开始并没想到啊...


     代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cstdio>
    #define lson (x << 1)
    #define rson ((x << 1) | 1)
    using namespace std;
    
    const int MAXN = 20005, MAXK = 50005;
    
    struct Line{
    	int l, r, siz;
    	bool operator < (const Line& b) const {
    		return ((r == b.r) ? (l > b.l) : (r < b.r));
    	}
    }que[MAXK];
    struct Node{
    	int minn, lzy;
    }t[MAXN << 2];
    int n, k, c, res;
    
    inline int rd() {
    	register int x = 0;
    	register char c = getchar();
    	while(!isdigit(c)) c = getchar();
    	while(isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return x;
    }
    inline void pushup(int x) {
    	t[x].minn = min(t[lson].minn, t[rson].minn);
    	return;
    }
    inline void pushdown(int x) {
    	register int lzy = t[x].lzy;
    	t[lson].lzy += lzy;
    	t[rson].lzy += lzy;
    	t[lson].minn += lzy;
    	t[rson].minn += lzy;
    	t[x].lzy = 0;
    	return;
    }
    void update(int L, int R, int l, int r, int x, int val) {
    	if(L <= l && r <= R) {
    		t[x].lzy += val;
    		t[x].minn += val;
    		return;
    	}
    	int mid = ((l + r) >> 1);
    	if(t[x].lzy) pushdown(x);
    	if(L <= mid) update(L, R, l, mid, lson, val);
    	if(mid < R) update(L, R, mid + 1, r, rson, val);
    	pushup(x);
    	return;
    }
    int query(int L, int R, int l, int r, int x) {
    	if(L <= l && r <= R) return t[x].minn;
    	int mid = ((l + r) >> 1), ans = 0x3f3f3f3f;
    	if(t[x].lzy) pushdown(x);
    	if(L <= mid) ans = query(L, R, l, mid, lson);
    	if(mid < R) ans = min(ans, query(L, R, mid + 1, r, rson));
    	return ans;
    }
    
    int main() {
    	k = rd(); n = rd(); c = rd();
    	update(1, n, 1, n, 1, c);
    	for(int i = 1; i <= k; ++i) {
    		que[i].l = rd();
    		que[i].r = rd();
    		que[i].siz = rd();
    	}
    	sort(que + 1, que + k + 1);
    	register int tmp = 0;
    	for(int i = 1; i <= k; ++i) {
    		tmp = min(que[i].siz, query(que[i].l, que[i].r - 1, 1, n, 1));
    		if(!tmp) continue;
    		res += tmp;
    		update(que[i].l, que[i].r - 1, 1, n, 1, -tmp);
    	}
    	printf("%d
    ", res);
    	return 0;
    }
  • 相关阅读:
    四色定理+dfs(poj 1129)
    栈的应用:表达式求值运算
    多重背包 (poj 1014)
    poj 1080 (LCS变形)
    KMP算法(快速模式匹配)
    贪心+构造( Codeforces Round #344 (Div. 2))
    JavaScript Ajax
    Canvas绘图
    TCP/IP协议
    移动端click事件延迟300ms到底是怎么回事,该如何解决?
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9762495.html
Copyright © 2020-2023  润新知