CF2063D Game With Triangles 反悔贪心

传送门

一开始想法是对的,但是写的丑了导致大数据一直没过去

由于我们只关心所选的区间长度和剩余的点的数量,并不关心具体选了哪些点,所以按照反悔贪心一贯的,用优先队列来储存选了哪些区间和哪些区间未选,剩余点的数量用n,m表示即可。用l,r双指针的方式从首尾选区间固然可以,但是这样就维护了额外的多余的量,容易出错

```cpp
#include<bits/stdc++.h>
    
using namespace std;
    
long long t;
const long long N = 2e5 + 10;
long long n,m,k;
long long a[N],b[N],ans[N];
    
void solve() {
    for(long long i = 0;i <= k;i++) ans[i] = 0;
    cin >> n >> m;
    for(long long i = 1;i <= n;i++) cin >> a[i];
    for(long long i = 1;i <= m;i++) cin >> b[i];
    sort(a + 1,a + 1 + n);
    sort(b + 1,b + 1 + m);
    if(min(n,m) * 2 <= max(n,m)) k = min(n,m);
    else k = (n + m) / 3;
    cout << k << '\n';
    priority_queue<long long> qa,qb;
    priority_queue<long long,vector<long long>,greater<long long> > pa,pb;
    //由于我仅仅只关注上下两条线各自点的数量和最大区间长度,并不关心该区间两端端点具体是什么,所以我们采用优先队列储存区间长度,n,m记录各自剩余点的个数即可,反悔的过程当中也仅仅只要用到各自剩余点的个数和已经加了的的区间长度
    for(long long i = 1;i <= n / 2;i++) qa.push(a[n - i + 1] - a[i]);
    for(long long i = 1;i <= m / 2;i++) qb.push(b[m - i + 1] - b[i]);
    long long tmp = n + m,res = 0;
    while(1) {
        if(n >= 2 && m >= 2) {
            n--,m--;
            if(qa.top() > qb.top()) res += qa.top(),n--,pa.push(qa.top()),qa.pop();
            else res += qb.top(),m--,pb.push(qb.top()),qb.pop();
        }
        else if(n >= 2) {
            if(m == 0) {
                if(pb.empty()) break;
                res -= pb.top();
                pb.pop();
                m += 2;n++;
            }
            res += qa.top();
            n -= 2;m--;
            pa.push(qa.top());
            qa.pop();
        }
        else if(m >= 2) {
            if(n == 0) {
                if(pa.empty()) break;
                res -= pa.top();
                pa.pop();
                n += 2;m++;
            }
            res += qb.top();
            m -= 2;n--;
            pb.push(qb.top());
            qb.pop();
        }
        else break;
        ans[(tmp - n - m) / 3] = max(ans[(tmp - n - m) / 3],res);
    }
    for(long long i = 1;i <= k;i++) cout << ans[i] << ' ';
    cout << '\n';
}
    
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin >> t;
    while(t--) solve();
    
    return 0;
}
posted @   孤枕  阅读(0)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
相见争如不见,多情何似无情。