LGJOI20230812
LGJ水场。
这场总体题比较简单,所以分比较高。
A
有
solution:
简单贪心。将工作按截止日期从小到大排序。用一个堆维护当前决定进行的工作的报酬,每次尝试加入一项工作,如果超过了截止时间就从堆中取出报酬最小的工作,如果其报酬小于当前工作的报酬就将其移出堆并让当前工作入堆并更新报酬。
code
#include<iostream> #include<fstream> #include<algorithm> #include<queue> #define int long long using namespace std; int T, n; struct node_t{ int val, r; }a[2000005]; bool cmp(node_t u, node_t v){ return u.r == v.r ? u.val > v.val : u.r < v.r; } priority_queue<int> que; int ans, cnt; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> T >> n; for(int i = 1; i <= n; i ++) cin >> a[i].r >> a[i].val, a[i].r = min(a[i].r, T); sort(a + 1, a + n + 1, cmp); for(int i = 1; i <= n; i ++){ if(cnt + 1 <= a[i].r){ ans += a[i].val; que.push(-a[i].val); cnt ++; } else{ int last = -que.top(); if(a[i].val < last) continue; que.pop(); ans -= last, ans += a[i].val; que.push(-a[i].val); } } cout << ans; return 0; }
B
有
solution
假设对于第
code
#include<iostream> #include<fstream> #include<algorithm> #include<cstring> #pragma GCC optmize(3,"Ofast","inline") #define int long long using namespace std; int n, M, N, tot; int w[405], c[405]; int q1[405], q2[405]; int cnt[205]; const int inf = 0x3f3f3f3f3f3f3f3f; int f[2][300005], nw; int q[300005], head = 1, tail = 0; int sum; signed main(){ ios::sync_with_stdio(0); cin >> n >> N; for(int i = 1; i <= n; i ++) cin >> q1[i]; for(int i = 1; i <= n; i ++) cin >> q2[i], sum += q1[i] * q2[i]; for(int i = 1; i <= n; i ++) cnt[q1[i]] += q2[i]; for(int i = 1; i <= 200; i ++) if(cnt[i]) w[++ tot] = i, c[tot] = cnt[i]; for(int i = tot + 1; i <= tot * 2; i ++) w[i] = -w[i - tot], c[i] = inf; n = tot; memset(f, 0x3f, sizeof(f)); f[0][0] = 0; M = N * 2; for(int i = 1; i <= n; i ++){ nw = nw ^ 1; for(int j = 0; j < w[i]; j ++){ head = 1, tail = 1, q[1] = 0; f[nw][j] = f[nw ^ 1][j]; for(int k = 1; k <= (M - j) / w[i]; k ++){ while(head <= tail && k - q[head] > c[i]) head ++; while(head <= tail && f[nw ^ 1][j + k * w[i]] <= f[nw ^ 1][j + q[tail] * w[i]] + (k - q[tail])) tail --; q[++ tail] = k; f[nw][j + k * w[i]] = f[nw ^ 1][j + q[head] * w[i]] + (k - q[head]); } } } for(int i = n + 1; i <= 2 * n; i ++){ for(int j = M; j >= 1; j --){ if(j - w[i] > M) continue; f[nw][j] = min(f[nw][j], f[nw][j - w[i]] + 1); } } if(f[nw][N] < inf) cout << f[nw][N]; else cout << -1; return 0; }
本文作者:AzusidNya の 部屋
本文链接:https://www.cnblogs.com/AzusidNya/p/17624907.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步