算法分析第十一次作业

1. 问题

   给出n个数,求出最优前缀码

2. 解析

  每次选出两个数,将两个数合并成一个数,查剩下的有序数组,每一次减少一个数,最后的数就是答案

3. 设计

  我们可以使用权值线段树,来实现O(logn)的插入以及O(logn)的删除,当然我们也可以使用链表等手段,这里我使用了multiset的c++容器来实现插入与删除;

    

1 for(int i=1;i<=n-1;i++){
2     int x=*s.begin();
3     s.erase(s.begin());
4     int y=*s.begin();
5     s.erase(s.begin());
6     s.insert(x+y);
7 }

4. 分析

  O(nlogn)

5. 源码

https://github.com/Tinkerllt/algorithm-work.git

 1 #include<stdio.h>
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<bitset>
 8 #include<set>
 9 #include<deque>
10 #include<queue>
11 #include<vector>
12 //#include<unordered_map>
13 #include<map>
14 #include<stack>
15 using namespace std;
16 #define ll long long
17 #define ull unsigned long long
18 #define pii pair<int,int>
19 #define Pii pair<ll,int>
20 #define m_p make_pair
21 #define l_b lower_bound
22 #define u_b upper_bound
23 const int inf = 0x3f3f3f3f;
24 const ll linf = 0x3f3f3f3f3f3f3f3f;
25 const int maxn = 2e6 + 11;
26 const int maxm = 600 + 11;
27 const int mod = 1e9 + 7;
28 const double eps = 1e-5;
29 inline ll rd() { ll x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }return x * f; }
30 inline ll qpow(ll a, ll b, ll p) { ll res = 1; while (b) { if (b & 1) { res *= a; res %= p; }b >>= 1; a = a * a%p; }return res; }
31 inline ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a%b); }
32 //iterator
33 //head
34 //priority_queue
35 multiset<int>s; 
36 int main() {
37     int n=rd();
38     for(int i=1;i<=n;i++){
39         int x=rd();
40         s.insert(x);
41     } 
42     for(int i=1;i<=n-1;i++){
43         int x=*s.begin();
44         s.erase(s.begin());
45         int y=*s.begin();
46         s.erase(s.begin());
47         s.insert(x+y);
48     }
49     printf("%d
",*s.begin());
50 }
View Code
原文地址:https://www.cnblogs.com/tinkerx/p/12878164.html