題目鏈接:hdu 4869 Task
題目大意:有n台機器,m個任務,每個機器和任務都有有xi和yi,要求機器的xi,yi均大於等於任務的xi和yi才能執行任務。每台機器一天只能執行一個任務。要求完成的任務數盡量多,並且說金額盡量大。完成每個任務的金額為xi?500+yi?2
解題思路:貪心,mach[i][j]表示等級為i,時間為j的機器數量,task[i][j]表示等級為i,時間為j的機器數量。每次優先減少i,因為對應等級減少100,對應的金額代價也不會減少超過500(即時間減少1)。
每次mach[i][j]要加上mach[i][j+1],即上面沒有被使用的機器,tmp記錄當前j下,等級大於i的機器個數。
#include
#include
#include
#include
using namespace std;
typedef __int64 ll;
const int maxt = 1440;
const int maxd = 100;
int N, M;
int mach[maxd+10][maxt+10], task[maxd+10][maxt+10];
void init () {
int a, b;
memset(mach, 0, sizeof(mach));
memset(task, 0, sizeof(task));
for (int i = 0; i < N; i++) {
scanf("%d%d", &a, &b);
mach[b][a]++;
}
/*
for (int i = maxd; i >= 0; i--)
for (int j = maxt; j >= 0; j--)
mach[i][j] = mach[i][j] + mach[i+1][j] + mach[i][j+1] - mach[i+1][j+1];
*/
for (int i = 0; i < M; i++) {
scanf("%d%d", &a, &b);
task[b][a]++;
}
}
void solve () {
ll ans = 0;
int cnt = 0;
for (int j = maxt; j >= 0; j--) {
int tmp = 0;
for (int i = maxd; i >= 0; i--) {
mach[i][j] += mach[i][j+1];
tmp += mach[i][j];
int k = min(tmp, task[i][j]);
ans += (ll)k * (2LL * i + 500LL * j);
tmp -= k;
cnt += k;
for (int x = i; x <= maxd; x++) {
int p = min(mach[x][j], k);
k -= p;
mach[x][j] -= p;
if (k == 0)
break;
}
}
}
printf("%d %I64d\n", cnt, ans);
}
int main () {
while (scanf("%d%d", &N, &M) == 2 && N + M) {
init();
solve();
}
return 0;
}