zoukankan      html  css  js  c++  java
  • P6033 [NOIP2004 提高组] 合并果子 加强版 题解

    CSDN同步

    原题链接

    我们先解决弱化版,即 P1090 ,对于 (n leq 10^5) 的数据,如何解决?

    很明显我们可以采取贪心,对于 (a leq b leq c),我们应先将 (a,b) 先合并,再与 (c) 合并。具体证明:

    先并 (a,b)((a+b)+(a+b+c)),而其余答案为 ((a+c)+(a+b+c))((b+c)+(a+b+c)),均比其劣。于是可说明,每次把两个最小的并,总是最优的。并完之后我们需要把 (a+b) 丢到数组里,再重新排序。

    当然我们不需要每次都重新排序。可以用插入排序维护,或者更方便地用优先队列维护,时间复杂度均为 (mathcal{O}(n log n)).

    强化版(即本题),如何解决?

    考虑到,由于 (a_i leq 10^5 (forall i in [1,n])),因此可以用桶排序来进行线性的排序。然后主要是如何维护 (a+b) 的位置?

    考虑把排序过后的原数列放在一个队列(非优先队列)(q1) 中,把由于合并产生的数放在另一个队列 (q2) 中。每次从两个队列中挑出最小值和次小值将其踢出,然后再放到 (q2) 中。由于每次合并的总是当前最小的,因此 (q2) 满足单调性。(q1) 显然满足单调性,因此可保证正确。

    时间复杂度:(mathcal{O}(n)).

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N=1e7+1;
    
    inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
    	int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
    
    inline void write(int x) {
    	if(x<0) {putchar('-');write(-x);return;}
    	if(x<10) {putchar(char(x%10+'0'));return;}
    	write(x/10);putchar(char(x%10+'0'));
    }
    
    int n,a[N],h[N];
    ll ans=0;
    queue<ll> q1,q2;
    
    int main() {
    	n=read();
    	for(int i=1;i<=n;i++) h[read()]++;
    	for(int i=1;i<=100000;i++)
    	for(int j=1;j<=h[i];j++) q1.push(i);
    	for(int i=1;i<n;i++) {
    		ll x,y;
    		if(q2.empty() || !q1.empty() && q1.front()<q2.front()) x=q1.front(),q1.pop();
    		else x=q2.front(),q2.pop();
    		if(q2.empty() || !q1.empty() && q1.front()<q2.front()) y=q1.front(),q1.pop();
    		else y=q2.front(),q2.pop();
    		ans+=x+y; q2.push(x+y);
    	} printf("%lld
    ",ans);
    	return 0;
    }
    
    
    
    简易的代码胜过复杂的说教。
  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/bifanwen/p/15081197.html
Copyright © 2011-2022 走看看