poj3253

来源:互联网 发布:兰州知行学院官网 编辑:程序博客网 时间:2024/06/05 14:50

挑战程序设计竞赛p47

注意到木板的分割是一个二叉树,每个最后的Li都是一个叶子节点,所以实质上就是构造哈夫曼树。用快排和插入排序来构造了一个哈夫曼树。


#include <iostream>#include <algorithm>using namespace std;typedef long long LL;int N;const int maxn=20005;int L[maxn];LL ans;void Insert_Sort(int lo,int hi){for(int i=lo+1;i<hi;i++){for(int j=i;j>lo&&L[j]<L[j-1];j--){swap(L[j],L[j-1]);}}}int main(int argc, char const *argv[]){cin>>N;for(int i=0;i<N;i++){cin>>L[i];}sort(L,L+N);for(int i=1;i<N;i++){int min=L[i]+L[i-1];ans+=(long long)min;L[i]=min;Insert_Sort(i,N);}cout<<ans<<endl;return 0;}

要特别小心:插入排序是O(n^2),其实这里很可能是败笔

应该用一个堆来维护有序性质,这样是O(3NlogN)

用堆的写法

#include <iostream>using namespace std;const int maxn=20015;int a[maxn];void exch(int m,int n){ int t = a[n]; a[n] = a[m]; a[m] = t;} void swim(int n){while(n/2 && a[n]<a[n/2]){exch(n,n/2);n/=2;}}void sink(int cur,int n){while(cur*2<=n){int j=2*cur;if(j+1<=n && a[j+1]<a[j]) j++;if(a[cur]<a[j]) break;exch(cur,j);cur*=2;}}int main(int argc, char const *argv[]){int N;cin>>N;for(int i=1;i<=N;i++){cin>>a[i];swim(i);}long long ans=0;for(int i=N;i>1;){int first=a[1];a[1]=a[i--];sink(1,i);int second=a[1];a[1]=a[i];sink(1,i-1);ans+=first+second;a[i]=first+second;swim(i);}cout<<ans<<endl;return 0;}

全部换成long long 即可,因为后面会很大。。。。。。。。。。没注意数据范围的zz

0 0
原创粉丝点击