Bzoj2034 2009国家集训队试题 最大收益 贪心+各种优化+二分图

来源:互联网 发布:dnf游戏数据怎么删除 编辑:程序博客网 时间:2024/06/10 04:14

这个题真的是太神了。。。

从一开始枚举到最后n方的转化,各种优化基本都用到了极致。。。。


FQW的题解写了好多,个人感觉我完全没有在这里废话的必要了

直接看这里


各种方法真的是应有尽有


大概说下


首先可以想到一个KM算法求二分图最大代权匹配的问题对吧

左边是任务右边是时间

但是这个是三次方啊


那我们就按价值排序,这样就不用代权匹配了但是还是三方


但是左边在右边的连线是单调的。。。

所以就可以贪心判断了。。。

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define MAX 5010#define rep(i,j,k) for(int i = j; i <= k; i++)using namespace std;int n, Link[MAX];long long ans = 0;int b[MAX];struct wbysr{int Begin, end, value;} a[MAX];bool cmp (wbysr a1, wbysr a2){return a1.Begin < a2.Begin || (a1.Begin == a2.Begin && a1.end < a2.end);}bool cmp2 (wbysr a1, wbysr a2){return a1.value > a2.value;}bool find (int now, int x){if (b[x] > a[now].end)return 0;if (!Link[x]){Link[x] = now;return 1;}int j = Link[x];if (a[now].end > a[j].end)return find (now,x + 1);else{if (find(j, x + 1)){Link[x] = now;return 1;}}return 0;}int main(){scanf ("%d", &n);rep (i, 1, n)scanf ("%d%d%d", &a[i].Begin, &a[i].end, &a[i].value);sort (a + 1, a + 1 + n, cmp);int now = 0;rep (i, 1, n){now = max (now + 1, a[i].Begin);b[i] = now;}sort (a + 1, a + 1 + n, cmp2);b[n+1] = 0x7fffffff / 3;rep (i, 1, n){int j;for (j = 1; j <= n; j++)if (b[j] >= a[i].Begin && b[j] <= a[i].end)break;if (find(i, j))ans += a[i].value;}cout << ans << endl;return 0;}

1 0
原创粉丝点击