首页 > 代码库 > UVa10954 Add All (Huffman编码,优先队列)

UVa10954 Add All (Huffman编码,优先队列)

链接:http://vjudge.net/problem/UVA-10954

分析:Huffman编码建立过程,每次贪心选取两个当前最小数,从集合中删去,然后把它们的和放回集合,用优先队列去模拟集合而且可以优化取最小数过程。

 

 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5  6 const int maxm = 500 + 5; 7  8 int m, k, p[maxm]; 9 10 int solve(long long maxp) {11     int ans = 1;12     long long done = 0;13     for (int i = 0; i < m; i++) {14         if (done + p[i] <= maxp) done += p[i];15         else { done = p[i]; ans++; }16     }17     return ans;18 }19 20 int last[maxm];21 void print(long long ans) {22     long long done = 0;23     int remain = k;24     memset(last, 0, sizeof(last));25     for (int i = m - 1; i >= 0; i--) {26         if (done + p[i] > ans || i + 1 < remain) {27             last[i] = 1; remain--; done = p[i];28         } else done += p[i];29     }30     for (int i = 0; i < m-1; i++) {31         printf("%d ", p[i]);32         if (last[i]) printf("/ ");33     }34     printf("%d\n", p[m-1]);35 }36 37 int main() {38     int T;39     scanf("%d", &T);40     while (T--) {41         scanf("%d%d", &m, &k);42         long long tot = 0;43         int maxp = -1;44         for (int i = 0; i < m; i++) {45             scanf("%d", &p[i]);46             tot += p[i];47             maxp = max(maxp, p[i]);48         }49         long long L = maxp, R = tot;50         while (L < R) {51             long long M = L + (R-L)/2;52             if (solve(M) <= k) R = M;53             else L = M+1;54         }55         print(L);56     }57     return 0;58 }

 

UVa10954 Add All (Huffman编码,优先队列)