作业介绍
// 反悔贪心
// 先留着,如果后面有更优,反悔,换了你
// 任务而言,截至时间 和 利润
// 按照时间排序,依次完成,
// 如果到了某个任务,排不出时间,去和之前利润最小的任务比较
// 选最优的
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
pair<int, int > a[N];
long long res;
priority_queue<int> q; // 存储之前已经完成的任务的收益
int n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i].first >> a[i].second;
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) {
if (a[i].first <= q.size()) {
// 去和已经完成任务的去进行比较,
if (a[i].second > -q.top()) {
res += a[i].second - (-q.top()); // 多增加的收益
q.pop();
q.push(-a[i].second);
}
} else {
q.push(-a[i].second);
res += a[i].second;
}
}
cout << res;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n, res;
// 优先队列,默认先出大的
// 出小的, 前面加负数, 大变小,小变大
priority_queue<int> q;
int main() {
cin >> n;
while (n--) {
int x;
cin >> x;
q.push(-x); // 将 x 压入优先队列中
}
while (q.size() > 1) {
// q.top() 取出队首的值
int a = -q.top();
q.pop(); // 弹出队首
// q.top() 取出队首的值
int b = -q.top();
q.pop(); // 弹出队首
res += a + b;
q.push(-(a + b));
}
cout << res;
return 0;
}
贪心策略: 按照 左手 *右手 的乘积从小到大排序
//同一个产品,要先在 A 加工
//然后去 B 加工
//n 个产品,求全部加工完的最短时间
//两个产品
//x 10 20 : a[i] < b[i] , a[i] 小的在前面
//y 20 10
//x - y:10 + 20 + 10 = 40
//y - x:20 + 10 + 20 = 50
//
//x 20 10
//y 20 5 a[i]>=b[i] , b[i] 小的在后面
//x - y : 20 + 20 + 5 = 45
//y - x : 20 + 20 + 10 = 50
// 智力大冲浪
// 优先完成扣钱最多的游戏
// 时间安排?
// 假设截至时间是5 1 2 3 4 5
// 时间选择,从后往前选最好
#include <bits/stdc++.h>
using namespace std;
int n, cnt, L, h, x, r;
struct node {
double x, y;
} ;
node a[20005];
bool cmp(node x, node y) {
return x.x < y.x;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n >> L >> h;
cnt = 0;
for (int i = 1; i <= n; i++) {
cin >> x >> r;
if (r <= h / 2)
continue; //喷水装置不能覆盖草坪宽度
cnt++;
a[cnt].x = x - sqrt(r * r - h * h / 4.0);
a[cnt].y = x + sqrt(r * r - h * h / 4.0);
}
sort(a + 1, a + 1 + cnt, cmp);
double t = 0;
int ans = 0, bj = 1, i = 1;
while (t < L) {
ans++;
double s = t;
for (; a[i].x <= s && i <= cnt; i++) //依次找能够覆盖L点的最大右端点
if (t < a[i].y)
t = a[i].y;
if (t == s && s < L) {
cout << -1 << endl;
bj = 0;
break;
}
}
if (bj)
cout << ans << endl;
}
return 0;
}
//先对区间右端点从小到大排序
//种树的时候,优先选择当前区间最右边的点去种
//r 已经从小到大排序, x - 1, x ,
//x 是更有可能性被下一个区间覆盖
//当 x - 1 被下一个区间覆盖了以后,x 肯定也被覆盖了
//但是 x 被覆盖了,x - 1 不一定被覆盖,
//优先选择从区间的右端点往左端点开始种树
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
const int M = 3e4 + 10;
int n, res, h;
bool vis[M]; // 标记这个点有没有种树
struct node {
int b, e, t;
bool operator < (const node a) {
return e < a.e;
}
};
node a[N];
int main() {
cin >> h >> n;
for (int i = 1; i <= n; i++)
cin >> a[i].b >> a[i].e >> a[i].t;
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) {
int t = a[i].t;
for (int j = a[i].b; j <= a[i].e && t; j++)
if (vis[j])
t--; //已经种好的树,减去
// 剩下没种的树
for (int j = a[i].e; t ; j--) {
if (vis[j])
continue;
vis[j] = 1; // 当前位置种树
res++;
t--;
}
}
cout << res;
return 0;
}
// 优先选择结束时间最早的
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, res;
struct node {
int l, r;
// 重载比较运算符
bool operator < (const node a) {
if (r != a.r)
return r < a.r;
return l < a.l;
}
};
node a[N];
int main() {
freopen("huodong.in", "r", stdin);
freopen("huodong.out", "w", stdout);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i].l >> a[i].r;
sort(a + 1, a + 1 + n);
int last = a[1].r; // 记录上一个的开始时间
res = 1;
for (int i = 1; i <= n; i++) {
if (a[i].l >= last)
res++, last = a[i].r;
}
cout << res;
return 0;
}
题目
认领作业后才可以查看作业内容。
- 状态
- 正在进行…
- 题目
- 18
- 开始时间
- 2026-7-1 0:00
- 截止时间
- 2026-8-31 23:59
- 可延期
- 24 小时