工作调度
记录第一次的反悔贪心题目,用优先队列维护报酬
先按照截止时间从小到大排序,然后遍历所有的工作,如果没有截止时间还没有过就先选上,当遍历到截止时间过了之后,此时将队列中报酬最小的弹出,用现在的工作替换,这就是后悔的过程。
/**
* @file P2949.cpp
* @author ruilong fan ()
* @brief 反悔贪心 工作调度
* @version 0.1
* @date 2021-12-11
*
* @copyright Copyright (c) 2021
*
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
struct job
{
ll d, p;
}jobs[N];
bool cmp(job a, job b) {return a.d < b.d;}//安排截止时间排序
ll n, res;
void run()
{
priority_queue<ll, vector<ll>, greater<ll> > pp;
cin >> n;
for (int i = 1; i <= n; i ++)
{
int d, p;
cin >> d >> p;
jobs[i] = {d, p};
}
sort(jobs + 1, jobs + n + 1, cmp);
for (int i = 1; i <= n; i ++)
{
if (jobs[i].d <= pp.size()) //超过截止时间
{
if (jobs[i].p > pp.top()) // 后悔做法
{
res += jobs[i].p - pp.top();
pp.pop();
pp.push(jobs[i].p);
}
} else {
res += jobs[i].p;
pp.push(jobs[i].p);
}
}
cout << res << endl;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
run();
return 0;
}
修理牛棚
将有牛的牛棚排序然后计算出相邻之间的差值,然后从第一个开始遍历,遍历到某个表示从这里截断,直到截为m块。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1010;
int a[N], sub[N];//sub表示有牛的牛棚之间差值
int res;
bool cmp(int x, int y)
{
return x > y;
}
void run()
{
int m, s, c;
cin >> m >> s >> c;
for (int i = 1; i <= c; i ++)
cin >> a[i];
if (c <= m)
{
cout << c << endl;
return ;
}
sort(a + 1, a + 1 + c);
res = a[c] - a[1] + 1;
for (int i = 1; i <= c; i ++)
sub[i - 1] = a[i] - a[i - 1];// 必须是sub[i-1]排序时可以忽略掉0
sort(sub + 1, sub + c, cmp);
for (int i = 1; i < m; i ++)//数学知识,将一个木棍分为m份,需要截m - 1次
{
res -= sub[i] - 1;
}
cout << res << endl;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
freopen("data.in", "r", stdin);
run();
return 0;
}