试题描述
|
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 |
输入
|
包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
|
输出
|
包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。
|
输入示例
|
3
1 2 9 |
输出示例
|
15
|
其他说明
|
数据范围:保证有n<=10000。
|
哈夫曼树啦,贪心策略谁都能想到吧
写个Treap,竟然WA了一发TAT
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define lc ch[x][0] #define rc ch[x][1] #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=10010; struct Node { Node* ch[2]; int r,v; }nodes[maxn],*null=&nodes[0],*root=null; queue<Node*> Q;int ToT; Node* newnode(int v) { Node* o; if(Q.empty()) o=&nodes[++ToT]; else o=Q.front(),Q.pop(); o->v=v;o->r=rand();o->ch[0]=o->ch[1]=null; return o; } void del(Node* &o) {Q.push(o);o=null;} void rotate(Node* &o,int d) { Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;o=k; } void insert(Node* &o,int v) { if(o==null) o=newnode(v); else { int d=v>o->v;insert(o->ch[d],v); if(o->ch[d]->r>o->r) rotate(o,d^1); } } void remove(Node* &o,int v) { if(o->v==v) { Node* k=o; if(o->ch[0]==null) o=o->ch[1],del(k); else if(o->ch[1]==null) o=o->ch[0],del(k); else { int d=o->ch[0]->v>o->ch[1]->v; rotate(o,d);remove(o->ch[d],v); } } else remove(o->ch[v>o->v],v); } int query(Node* o) { while(o->ch[0]!=null) o=o->ch[0]; return o->v; } void print(Node* &o) { if(o==null) return; print(o->ch[0]); printf("%d ",o->v); print(o->ch[1]); } int main() { int n=read(),ans=0; rep(1,n) insert(root,read()); while(--n) { int x=query(root);remove(root,x); int y=query(root);remove(root,y); ans+=x+y;insert(root,x+y); } printf("%d ",ans); return 0; }
写个利用单调性的做法,竟然又WA了一发233
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define lc ch[x][0] #define rc ch[x][1] #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=10010; int A[maxn],f=1,B[maxn],l=1,r; int query() { if(l<=r&&A[f]>B[l]) return B[l++]; return A[f++]; } int main() { int n=read(),ans=0; rep(1,n) A[i]=read(); sort(A+1,A+n+1);A[n+1]=1e9; while(--n) { int x=query(),y=query(); ans+=x+y;B[++r]=x+y; } printf("%d ",ans); return 0; }