【POJ】 3762 The Bonus Salary! 离散 + 费用流
来源:互联网 发布:linux给文件夹重命名 编辑:程序博客网 时间:2024/05/22 06:09
The Bonus Salary!
In order to encourage employees' productivity, ACM Company has made a new policy. At the beginning of a period, they give a list of tasks to each employee. In this list, each task is assigned a "productivity score". After the firstK days, the employee who gets the highest score will be awarded bonus salary.
Due to the difficulty of tasks, for task i-th:
It must be done from hh_Li : mm_Li : ss_Li to hh_Ri : mm_Ri : ss_Ri.This range of time is estimated very strictly so that anyone must use all of this time to finish the task.
Moreover, at a moment, each employee can only do at most one task. And as soon as he finishes a task, he can start doing another one immediately.
XYY is very hard-working. Unfortunately, he's never got the award. Thus, he asks you for some optimal strategy. That means, with a given list of tasks, which tasks he should do in the firstK days to maximize the total productivity score. Notice that one task can be done at most once.
Input
The first line contains 2 integers N and K (1 ≤ N ≤ 2000, 0 ≤ K ≤ 100), indicating the number of tasks and days respectively. This is followed byN lines; each line has the following format:
hh_Li:mm_Li:ss_Li hh_Ri:mm_Ri:ss_Ri w
Which means, the i-th task must be done fromhh_Li:mm_Li :ss_Li tohh_Ri :mm_Ri :ss_Ri and its productivity score isw. (0 ≤hh_Li,hh_Ri ≤ 23, 0 ≤mm_Li,mm_Ri,ss_Li,ss_Ri ≤ 59, 1 ≤w ≤ 10000). We use exactly 2 digits (possibly with a leading zero) to representhh,mm andss. It is guaranteed that the momenthh_Ri :mm_Ri :ss_Ri is strictly later thanhh_Li: mm_Li : ss_Li.
Output
The output only contains a nonnegative integer --- the maximum total productivity score.
Sample Input
The optimal strategy is:
Day1: Task1, Task 4
Day2: Task 3
The total productivity score is 2 + 4 + 10 = 16.
题目大意:给你n个时间段,每个时间段都有一个权值,k天的选择限制,每个时间段只能选择一次,其中同一天能选择互不重叠的时间段,最多选择k天。问怎样选择使得总权值和最大。
题目分析:就是区间K覆盖问题,解法同POJ 3680 Intervals 离散 + 费用流,首先,先对区间的端点进行离散化,之后对每个区间的左端点u和右端点v建边(u,v,1,-w),再对每个坐标点 i 建边(i,i + 1,k,0),设离散后最大的点的坐标为x,建立源汇点s = 0, t = x + 1,建边(x,t,1,0)。跑一次最小费用最大流,结果即花费的相反数。
- Time Limit: 2000MS
- Memory Limit: 65536K
- Total Submissions: 2321
- Accepted: 606
In order to encourage employees' productivity, ACM Company has made a new policy. At the beginning of a period, they give a list of tasks to each employee. In this list, each task is assigned a "productivity score". After the firstK days, the employee who gets the highest score will be awarded bonus salary.
Due to the difficulty of tasks, for task i-th:
It must be done from hh_Li : mm_Li : ss_Li to hh_Ri : mm_Ri : ss_Ri.This range of time is estimated very strictly so that anyone must use all of this time to finish the task.
Moreover, at a moment, each employee can only do at most one task. And as soon as he finishes a task, he can start doing another one immediately.
XYY is very hard-working. Unfortunately, he's never got the award. Thus, he asks you for some optimal strategy. That means, with a given list of tasks, which tasks he should do in the firstK days to maximize the total productivity score. Notice that one task can be done at most once.
Input
The first line contains 2 integers N and K (1 ≤ N ≤ 2000, 0 ≤ K ≤ 100), indicating the number of tasks and days respectively. This is followed byN lines; each line has the following format:
hh_Li:mm_Li:ss_Li hh_Ri:mm_Ri:ss_Ri w
Which means, the i-th task must be done fromhh_Li:mm_Li :ss_Li tohh_Ri :mm_Ri :ss_Ri and its productivity score isw. (0 ≤hh_Li,hh_Ri ≤ 23, 0 ≤mm_Li,mm_Ri,ss_Li,ss_Ri ≤ 59, 1 ≤w ≤ 10000). We use exactly 2 digits (possibly with a leading zero) to representhh,mm andss. It is guaranteed that the momenthh_Ri :mm_Ri :ss_Ri is strictly later thanhh_Li: mm_Li : ss_Li.
Output
The output only contains a nonnegative integer --- the maximum total productivity score.
Sample Input
5 209:00:00 09:30:00 209:40:00 10:00:00 309:29:00 09:59:00 1009:30:00 23:59:59 407:00:00 09:31:00 3
Sample Output16
HintThe optimal strategy is:
Day1: Task1, Task 4
Day2: Task 3
The total productivity score is 2 + 4 + 10 = 16.
题目大意:给你n个时间段,每个时间段都有一个权值,k天的选择限制,每个时间段只能选择一次,其中同一天能选择互不重叠的时间段,最多选择k天。问怎样选择使得总权值和最大。
题目分析:就是区间K覆盖问题,解法同POJ 3680 Intervals 离散 + 费用流,首先,先对区间的端点进行离散化,之后对每个区间的左端点u和右端点v建边(u,v,1,-w),再对每个坐标点 i 建边(i,i + 1,k,0),设离散后最大的点的坐标为x,建立源汇点s = 0, t = x + 1,建边(x,t,1,0)。跑一次最小费用最大流,结果即花费的相反数。
代码如下:
#include <stdio.h>#include <string.h>#include <algorithm>#define min(a, b) ((a) < (b) ? (a) : (b))#define REP(i, n) for(int i = 0; i < n; ++i)#define MS0(X) memset(X, 0, sizeof X)#define MS1(X) memset(X, -1, sizeof X)using namespace std;const int maxE = 1000000;const int maxN = 5000;const int maxM = 2014;const int oo = 0x3f3f3f3f;struct Edge{ int v, c, w, n;};Edge edge[maxE];int adj[maxN], l;int d[maxN], cur[maxN], f[maxN];int inq[maxN], Q[maxE], head, tail;int cost, flow, s, t;int n, m, cnt;struct Node{ int l, r, w;}a[maxN];int b[maxN];void addedge(int u, int v, int c, int w){ edge[l].v = v; edge[l].c = c; edge[l].w = w; edge[l].n = adj[u]; adj[u] = l++; edge[l].v = u; edge[l].c = 0; edge[l].w = -w; edge[l].n = adj[v]; adj[v] = l++;}int SPFA(){ memset(d, oo, sizeof d); memset(inq, 0, sizeof inq); head = tail = 0; d[s] = 0; f[s] = oo; cur[s] = -1; Q[tail++] = s; while(head != tail){ int u = Q[head++]; inq[u] = 0; for(int i = adj[u]; ~i; i = edge[i].n){ int v = edge[i].v; if(edge[i].c && d[v] > d[u] + edge[i].w){ d[v] = d[u] + edge[i].w; cur[v] = i; f[v] = min(edge[i].c, f[u]); if(!inq[v]){ inq[v] = 1; Q[tail++] = v; } } } } if(d[t] == oo) return 0; flow += f[t]; cost += f[t] * d[t]; for(int i = cur[t]; ~i; i = cur[edge[i ^ 1].v]){ edge[i].c -= f[t]; edge[i ^ 1].c += f[t]; } return 1;}int MCMF(){ flow = cost = 0; while(SPFA()); return cost;}void work(){ int hh, mm, ss, ww, cnt1; MS1(adj); l = 0; cnt = 0; REP(i, n){ scanf("%d:%d:%d", &hh, &mm, &ss); a[i].l = hh * 3600 + mm * 60 + ss; scanf("%d:%d:%d", &hh, &mm, &ss); a[i].r = hh * 3600 + mm * 60 + ss; scanf("%d", &a[i].w); } REP(i, n){ b[cnt++] = a[i].l; b[cnt++] = a[i].r; } sort(b, b + cnt); cnt1 = 0; REP(i, cnt) if(i && b[i] != b[cnt1]) b[++cnt1] = b[i]; cnt = ++cnt1; REP(i, n) REP(j, cnt) if(a[i].l == b[j]){ a[i].l = j; break; } REP(i, n) REP(j, cnt) if(a[i].r == b[j]){ a[i].r = j; break; } s = 0; t = cnt; REP(i, n) addedge(a[i].l, a[i].r, 1, -a[i].w); REP(i, cnt) addedge(i, i + 1, m, 0); printf("%d\n", -MCMF());}int main(){ while(~scanf("%d%d", &n, &m)) work(); return 0;}
0 0
- 【POJ】 3762 The Bonus Salary! 离散 + 费用流
- The Bonus Salary! (poj 3762 离散化+最小费用流)
- POJ 3762 The Bonus Salary! 最小费用最大流
- POJ 3762 The Bonus Salary!(费用流)
- poj 3762 The Bonus Salary! 需离散化
- POJ-3762-The Bonus Salary!
- POJ 3762 The Bonus Salary!(最小K覆盖)
- POJ 3762 The Bonus Salary!(区间k覆盖问题)
- 【POJ】 3680 Intervals 离散 + 费用流
- POJ 3680 Intervals(离散化+费用流)
- POJ 3680 费用流加离散化
- POJ 3680 Intervals 费用流+离散化
- poj 3680 Intervals (离散化+费用流)
- poj 3680 Intervals(离散化+费用流)
- poj3762 The Bonus Salary! (mcmf 区间K覆盖问题)
- POJ 3680 Intervals (最小费用最大流+离散化)
- poj 3680 Intervals(最大费用流+离散化)
- POJ 3680Intervals (拆点 || 离散) && 最大费用流
- 【POJ】 2135 Farm Tour 费用流
- 【POJ】 2516 Minimum Cost 费用流
- 【HDU】 4067 Random Maze 费用流
- 【POJ】 3422 Kaka’s Matrix Travels 费用流
- 【POJ】 3680 Intervals 离散 + 费用流
- 【POJ】 3762 The Bonus Salary! 离散 + 费用流
- Java学习之路之“我的第一个Java程序“HelloWorld””
- android 支付宝之网页支付和快捷支付
- Android: Bundle
- 分布式系统设计系列 -- 概要
- Linux 学习笔记---文件系统与LVM磁盘管理
- 如何值通过xib自定义cell
- uva 718 - Skyscraper Floors(数论+bfs)
- HDU 3694 Fermat Point in Quadrangle (费马定理求四边形的费马点)