2 条题解

  • 0
    @ 2025-11-9 21:31:37

    这题听出题人说可以贪心(但我不会 首先我们能想到的是 我们肯定是希望植物数量多的物种尽可能多配对 这样才能达成最多融合数 但是如果两种植物全部融合完了之后剩余一方的数量我们该如何处理呢?毕竟剩余植物数量不一定是第一多和第二多 再继续使用实际上存在出错的可能 如果大家多列一点应该是会有出错的可能的 所以我们实际上是希望当我们把剩余植物数量放回数列里面时 下次我们还能取出最多的和第二多的植物数量 这时候就可以用大根堆解决了 把植物数量存进大根堆里面 大根堆会自动把最多的植物数放在堆顶 我们把堆顶取出 并推出 再取一次 这样就能得到第一多(a)和第二多(b)的植物数量 再求min(a,b),加到我们的答案上去 a和b同时减去min(a,b)再把有剩余植物数量的放回堆里面 让堆自动排序 最后就能得出答案 唯一要注意的一点就是一开始题目可能会给0个数量 注意不要放进大根堆里面;

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int N = 2e5 + 10;
    const int MOD = 1e9 + 7;
    const int MOD9 = 998244353;
    const int MOD5 = 5;
    const ll inf = 2e10 + 7;
    ll q, d, t, n, k, mod,x,y,r,ans;
    string s;
    
    void solve()
    {
        ll ans=0,cnt=0,sum=0;
        cin>>n;
        if(n<=1)
        {
            cout<<0<<endl;
            return;
        }
        priority_queue<ll> pq; 
        for(int i=1;i<=n;++i)
        {
            ll x;
            cin>>x;
            if (x>0)
                pq.push(x);
        }
        if(pq.size()<2)
        {
            cout<<0<<endl;
            return;
        }
        while(pq.size()>=2)
        {
            ll a=pq.top();pq.pop();
            ll b=pq.top();pq.pop();
            ll m=min(a,b);
            ans+=m;
            a-=m;
            b-=m;
    //        cout<<a<<" "<<b<<endl;
            if(a>0)
                pq.push(a);
            if(b>0)
                pq.push(b);
        }
        cout<<ans<<endl;
    
    }
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	int tt;
    	tt = 1;
    	// cin >> tt;
    	while (tt--)
    		solve();
    	return 0;
    }
    

    超管留言:fw大王连代码块都不会用(¬‿¬)

    信息

    ID
    1127
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    221
    已通过
    37
    上传者