Topcoder SRM 726 Hard

来源:互联网 发布:ug4轴编程视频 编辑:程序博客网 时间:2024/06/01 09:39

链接:

link

题意:

N个任务,可以在[starti,finishi]这段时间内完成,完成了能获得costi的收益,每个时间最多完成一个任务,问最大收益。

题解:

不难发现这是个拟阵,所以可以从大到小排序之后贪心。

考虑对于一组区间,如何判断它是否合法也可以贪心:从左到右扫,每个位置安排r最小的点,记为ri,如果不存在ri=

考虑插入一个区间[x,x]是否合法,考虑i[i+1,ri]连边,如果能换那么x一定能到达

举个例子,xyz的意义就是x这个位置放了一个区间,所以原来x这个位置放的区间要调整到y,同理y要调整到z,由于z上面没有放区间,所以就不用调整了。

每次放完一个区间之后暴力算出哪些合法,用set维护一下就好了,详见代码。

复杂度O(nlogm+m2logm),其中m=max(finishi)

代码:

#include <bits/stdc++.h>#define xx first#define yy second#define mp make_pair#define pb push_back#define mset(x, y) memset(x, y, sizeof x)#define mcpy(x, y) memcpy(x, y, sizeof x)using namespace std;typedef long long LL;typedef pair <int, int> pii;const int MAXN = 2005;const int mod = 1e9 + 7;class HeroicSchedule{    int m, ans, rig[MAXN];    vector <int> r[MAXN];    vector <pii> a[MAXN];    set <int> s;    inline void Solve()    {        s.clear();        multiset <int> cur;        for (int i = 0; i < m; i ++)        {            for (auto j : r[i])                cur.insert(j);            if (cur.empty())                rig[i] = m;            else                rig[i] = *cur.begin(), cur.erase(cur.begin());        }        for (int i = m - 1; ~i; i --)            if (rig[i] == m || (!s.empty() && *s.begin() <= rig[i]))                s.insert(i);    }    public:        int getmax(int n, int A, int B, int C, int modStart, int modLen, int modCost)        {            ans = 0;            for (int i = 1, x = A, y, z; i <= n; i ++, x = (1LL * z * B + C) % mod)                y = (1LL * x * B + C) % mod, z = (1LL * y * B + C) % mod, a[z % modCost].pb(mp(x % modStart, y % modLen + x % modStart));            m = modStart + modLen - 1;            for (int i = 0; i < m; i ++)                s.insert(i);            for (int i = modCost - 1; i; i --)                for (auto e : a[i])                    if (!s.empty() && *s.rbegin() >= e.xx && *s.lower_bound(e.xx) <= e.yy)                        ans += i, r[e.xx].pb(e.yy), Solve();            return ans;        }};
原创粉丝点击