题意:
给出n个工作的耗时以及截止时间,每个时刻只完成一样工作,求超时最大的两个任务最少超出时间.
思路:
一看到截止时间就想到优先队列,后来发现不适用,题目是求最大值最小.
首先先按照最早截止时间排序,即截止时间越早优先级越高,如此先求出超时,同时保留罚时最大的值得下标,然后在暴力枚举此下标以前的所有任务,用意在将任务后调,看最大罚时的两个任务罚时是否会有所减少.即将枚举的任务放于第一轮求的最大罚时后面,看这种顺序是否改善罚时
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 505;
const int INF = 0x3f3f3f3f;
struct job {
int s,d;
}j[maxn];
int n, p;
bool cmp(const job&a, const job&b) {
return a.d<b.d;
}
void init() {
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%d%d", &j[i].s, &j[i].d);
sort(j, j+n, cmp);
}
int handle(int x) {
int a=0, b=0, t=0, q;
for(int i=0; i<=p; i++) {
if(i==x) continue;
t += j[i].s;
if(t - j[i].d > b) {
b = t - j[i].d;
}
if(b>a) swap(b, a);
}
t += j[x].s;
int k = max(0, t-j[x].d);
b = max(b, k);
return a+b;
}
int deal() {
int t=0, a=0, b=0;
for(int i=0; i<n; i++) {
t += j[i].s;
if(t-j[i].d >= b) {
b = t - j[i].d;
p = i;
}
if(b>a) swap(a, b);
}
int ans = a+b;
for(int i=0; i<p; i++) {
ans = min(ans, handle(i));
}
return ans;
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
init();
printf("%d\n", deal());
}
return 0;
}