[Homer] NOI2015

  Topic Link https://www.luogu.org/problem/P2168

  Subject to the effect of a given  n words the number of occurrences Wi , a find k  minimum total length binary prefix code obtained after the conversion, as well as ensure that the total length of the shortest length of the minimum of the longest string si.

  This problem is now regarded as the point of view of the NOI in a very simple (I actually concave out w), but it was said that this is a large problem, but stumped. The first is the question most probably taking too long because it is not very easy to understand, the other probably because it was not so common Huffman tree, few think of such a thing Huffman tree.

  Well, look at the title. The questions were very clear, the goal is to make the minimum total length after encoding, so now we must think about how to appear more often in code length is reduced as much as possible. But there is a limit in the title: a k-ary coding is not any prefix other coding. As a result, the practice of the subject points to the Huffman tree.

  


Huffman trees and Huffman coding

  Here simply repeat - (proof quote from the "data structure --C language to describe" Geng Guohua editor)

  Huffman tree characteristics: Weighted path length from the root to all leaf nodes of the shortest (that is, close to the right place to put a large root)

  Practice: the smallest sequence selected two points merged as a child node, the value of their root weight and, added to the root node of the original sequence, the above-described operation is repeated.

  Huffman encoding characteristics: 1. It is a prefix. Prefix code is subject to in kind, not before any other coding coded t items. Proof: Huffman coding of the coding sequence is the root side to the foliage of the path, which is equivalent to a sequence of edges, and can be seen from the characteristics of the tree, if the path A is the leftmost part of another path B, then B after A Therefore, the end is not a leaf a. Huffman coding and corresponds to the end of the leaf path, so that any one of Huffman coding will not completely overlap with the front portion of any other Huffman coding, Huffman coding is thus prefix code. 

 2. It is optimal prefix code. It is: for n characters, their frequency of use by the Huffman tree structure is a leaf, it can mean the shortest length encoding corresponding to various packet encoded. Proof: Since the Huffman code corresponding to each character right leaf frequency of use of the Huffman tree, and therefore, the length of the tree with a minimum weight tree, i.e. the minimum ΣWP, where W is the frequency of use of the i-th character P is the i-th character code length, which is a measure of the average formula packet length.

  Role: This is the data compression technology The basic idea eh!

  Method: Take heap to store things.


 

  Well, this question can be found in the idea entirely consistent with the Huffman tree. Then Huffman coding to try better. .

  Bigwigs have to analyze this question very thoroughly, so I draw the water just fine.

  Huffman tree is a binary tree. And this question is given in multi-branch tree. Well in fact expanding.

  We imagine the look after the well construction Huffman tree. First, the depth of the tree is the length of the uppermost point of the word is most frequently encoded word appears, the bottom appeared the least number of times. Take the sample to speak, it is this:

  Thus standard code, is 00, four points respectively;

According to Huffman's thoughts, each must take a minimum of two current point to point right into one of their parent node, until finally all nodes are combined into one. This question is to take k * k points synthetic layer nodes, their parent node is the junction point weights and son, so have been merged into a left. Here the "weights" can be understood: If I were a node, only one layer below me, a total of k point, my weight is the number of all my child nodes and appear. Who is to produce a combined I and my parent node, then the following sub-length I of all nodes are added 1, that is: "My is incorporated" in this operation, the total length is added: my weight * 1.

This question is so far almost stroke clear idea: the first find an appropriate data structure stored information, the weight saving point, then gradually merge point and update the weights of their parent nodes and high (deep) and record each step Effects of the total length caused by only the last point, and a high total output length vertex.

  Data structure recommended here - priority queue. This application is a very simple thing, try a few blind themselves would use. Priority queue here is to simulate a heap of similar structure, is always a small point that several right in front of the queue.

  Finally, a big detail. But according to the above ideas do if a situation occurs: As shown, n-=. 6, K =. 3.

If you just follow the above logic will have to engage in such a situation occurs, the red circle marked out the point could have been a number "2", it will not be a prefix and others, but it is wasted in this position. The solution: to properly catch some more points to the tree to become fully k-tree, the weight of these points is 0 (that certainly will be ranked at the bottom and has no effect on the answer, so you can achieve the above would have been the point squeeze up function), height is initialized to 1. The number of points is: k-1- (n-1)% (k-1). Gradually began to feel ~

After the operation point is the complement (or n = 6, k = 3): Here only need to make a point. The point we make is called ex. Ex is certainly the first to be stuffed into the bottom of the points. So when we went to the red circle just point out, in fact, the six o'clock position has been filled. This point will then merge together and the two points out of the blue circle. Figure:

So, we put it pushed the red circle in this position.

Ok. With code.

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std; 
int n,k;
long long lenth;
struct tree{
    long long val;
    long long h;
};
priority_queue<tree>q;        //优先队列 
bool operator<(tree a,tree b){
    if(a.val!=b.val) return a.val>b.val;  //Right from the low point to the high ranking 
    the else  return AH> BH;                 // otherwise prioritize a lower height (to simulate full-tree k 
} 
inline Long  Long max ( Long  Long A, Long  Long B) {
     IF (A> B) return A;
     the else  return B; 
} 
int main () { 
    CIN >> >> n- K;
     Long  Long REMAIN = 0 ;
     for ( int I = . 1 ; I <= n-; I ++ ) { 
        Tree A; 
        Scanf ( "LLD% " , A & .val); 
        AH = . 1 ; 
        q.push (A); 
    } 
    int Extra = 0 ;
     IF ((N- . 1 )% (- K- . 1 )) = - K-Extra . 1 - (N- . 1 )% (- k- . 1 );   //    * depth practice soul * 
    for ( int I = . 1 ; I <= extra; I ++) {             //   need to make up to a desired full k additional node tree 
        tree a; 
        a .val = 0 ; AH = . 1 ; 
        q.push (A); 
    }
    REMAIN= n-+ + Extra; 
    
    the while (REMAIN =! . 1 ) { 
        Tree A; 
        Long  Long CNT = . 1 , maxH = 0 , tmp = 0 ;
         the while (CNT <= K) {             // K binary 
            
            A = q.top () ;          // a is now the first team (minimum weight) in a Tree 
            q.pop (); 
            
            maxH = max (maxH, AH); // update the node currently being synthesized height 
            tmp + = a.val;         
            CNT + + ; 
        } 
        
    
        AH = + maxH . 1 ;
        a.val =tmp;
        lenth+=tmp;
        q.push(a);
        remain=remain-k+1; 
    }
    tree a=q.top() ;
    cout<<lenth<<endl<<a.h -1;
}

 

It should be the first time issued a document ... very nervous. Looked at the problem solution Luo Valley, found that a good similarity (Khan). .

 

Guess you like

Origin www.cnblogs.com/snowysniper/p/11323087.html