题目链接:点击打开链接
题意:
给定n个任务
下面[l, r]是n个任务需要占用的时间。
m个人
下面是m个人的空闲时间以及这个人至多能做的任务个数(一个人同一时刻只能做一个任务,即人是单线程的)
[l, r] num
问:
若任务不能被全部完成则输出NO
否则输出YES
输出每个任务是谁完成的。
思路:
把人和任务放一起按右端点排序。
若遇到了任务则把任务的左端点放到set里。
若遇到了人,则把set中>=人的左端点的 num个数删掉。
java:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Main {
static int N = 200050;
class Edge implements Comparable<Edge>{
long id, l;
public int compareTo(Edge o){
if(l != o.l)return Long.compare(l, o.l);
return Long.compare(id, o.id);
}
}
Edge edge(long a, long b){
Edge tmp = new Edge();
tmp.id = a; tmp.l = b;
return tmp;
}
class Node implements Comparable<Node>{
long l, r, id, num, op;
/* public Node(long a, long b, long c, long d, long e){
l = a; r = b; c = id; d = num; e = op;
}/**/
public int compareTo(Node o){
if(r != o.r)
return Long.compare(r, o.r);
return Long.compare(op, o.op);
}
}
Node cr(long a, long b, long c, long d, long e){
Node tmp = new Node();
tmp.l = a; tmp.r = b; tmp.id = c; tmp.num = d; tmp.op = e;
return tmp;
}
int[] b = new int[N], ans = new int[N];
ArrayList<Node> a = new ArrayList<>();
int n, m;
void init(){
n = cin.nextInt();
long l, r, num;
for(int i = 1; i <= n; i++)
{
l = cin.nextLong(); r = cin.nextLong();
a.add(cr(l, r, (long)i, 0L, 0L));
}
m = cin.nextInt();
for(int i = 1; i <= m; i++)
{
l = cin.nextLong(); r = cin.nextLong(); num = cin.nextLong();
a.add(cr(l, r, (long)i, num, 1L));
}
Collections.sort(a);
}
TreeSet set = new TreeSet();
Iterator p;
public void work(){
init();
set.clear();
set.add(edge(-1,0));
int siz = 0;
for(int i = 0; i < a.size(); i++)
{
if(a.get(i).op == 1){
while(set.size()>0 && a.get(i).num-->0){
Edge E = (Edge) set.ceiling(edge(0L, a.get(i).l));
if(E==null)break;
siz++;
ans[(int)E.id] = (int)a.get(i).id;
set.remove(E);
}
}
else
set.add(edge(a.get(i).id, a.get(i).l));
}
if(siz == n){
System.out.println("YES");
for(int i = 1; i <= n; i++)
System.out.print(ans[i]+" ");
}
else System.out.println("NO");
}
Main() {
cin = new Scanner(System.in);
}
public static void main(String[] args) {
Main e = new Main();
e.work();
}
public Scanner cin;
}
c:
#include <bits/stdc++.h>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
using namespace std;
typedef long long ll;
#define int ll
const int N = 200050;
int n, m;
struct node{
int op, l, r, num, id;
}a[N*2];
bool cmp(node x, node y){
if(x.r != y.r)
return x.r<y.r;
if(x.op!=y.op)
return x.op<y.op;
}
int top, b[N];
void input(){
top = 0;
for(int i = 1; i <= n; i++){
rd(a[top].l); rd(a[top].r);
a[top].op = 0;
a[top].id = i;
top++;
}
rd(m);
for(int i = 1; i <= m; i++){
rd(a[top].l); rd(a[top].r); rd(a[top].num);
a[top].op = 1;
a[top].id = i;
top++;
}
sort(a, a+top, cmp);
}
struct Edge{
int id, l;
bool operator<(const Edge&e)const{
if(e.l!=l)return e.l>l;
return e.id>id;
}
Edge(int a=0,int b=0):id(a),l(b){}
}tmp;
set<Edge>s;
set<Edge>::iterator p;
#undef int
int main(){
#define int ll
while(cin>>n){
input();
int ans = 0;
s.clear();
for(int i = 0; i < top; i++){
if(a[i].op){
while(s.size() && a[i].num--)
{
p = s.lower_bound(Edge(0, a[i].l));
if(p == s.end())break;
tmp = *p;
b[tmp.id] = a[i].id;
s.erase(p);
ans++;
}
}
else {
s.insert(Edge(a[i].id, a[i].l));
}
}
if(ans == n)
{
puts("YES");
for(int i = 1; i <= n; i++){pt(b[i]); putchar(' ');}
}
else puts("NO");
}
return 0;
}

本文探讨了在有限资源条件下,如何高效地分配任务给不同能力的个体,以实现任务的最大化完成。通过将人与任务按优先级排序,利用集合操作进行资源匹配,最终输出最优任务分配方案。
421

被折叠的 条评论
为什么被折叠?



