• 【c++刷题Day2】专题1背包T4


    这是C++刷题的Day2
    在这里插入图片描述
    🎈题目描述
    🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨
    Huffman Code is a commonly used optimal prefix code. Here is a simple introduction to Huffman Coding from wikipedia.

    The technique works by creating a binary tree of nodes. These can be stored in a regular array, the size of which depends on the number of symbols, S. A node can be either a leaf node or an internal node. Initially, all nodes are leaf nodes, which contain the symbol itself, the weight (frequency of appearance) of the symbol and optionally, a link to a parent node which makes it easy to read the code (in reverse) starting from a leaf node. Internal nodes contain symbol weight, links to two child nodes and the optional link to a parent node. As a common convention, bit '0' represents following the left child and bit '1' represents following the right child. A finished tree has up to n leaf nodes and n-1 internal nodes. A Huffman tree that omits unused symbols produces the most optimal code lengths.
    
    The simplest construction algorithm uses a priority queue where the node with lowest weight is given highest priority:
    
        Create a leaf node for each symbol and add it to the priority queue.
        While there is more than one node in the queue:
            Remove the two nodes of highest priority (lowest weight) from the queue
            Create a new internal node with these two nodes as children and with weight equal to the sum of the two nodes' weight.
            Add the new node to the queue.
        The remaining node is the root node and the tree is complete.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    For example, one day Edward wanted to send a string “aeaaaageqqqq” to his best friend Min as a gift. There are four symbols ‘a’, ‘e’, ‘g’, ‘q’ and so their weights are 5, 2, 1, 4.

    Firstly Edward merged the two symbols ‘e’ and ‘g’ with lowest weights and get a node with weight of 1 + 2 = 3. Then Edward merged two nodes of weight 3 and 4 and get a node with weight 3 + 4 = 7. Finally Edward merged the last two nodes. If we distribute the prefix ‘0’ to the smaller node, Edward can get the code of four symbols ‘0’, ‘101’, ‘100’, ‘11’.

    If we know the number of occurrences of each character in some content, can we compress it using Huffman Code and the number of '0’s is exactly E? More precisely, let the number of occurrences of the i-th character be Fi and the number of '0’s in its huffman code be Ci, we want to know whether there exists a specific huffman code satisfying that the sum of Fi * Ci is equal to E.
    Input

    There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

    The first line of each case contains a positive integer S (2 ≤ S ≤ 128), indicates the number of different symbols.

    The second line contains exactly S integers Fi (1 ≤ Fi ≤ 1000), indicates the number of occurrence of each symbol.

    The third line contains a non-negative integer E (0 ≤ E ≤ 108), indicates the expected number of '0’s.
    Output

    For each case, please output “Yes” if it can be satisfied and “No” in otherwise.
    Sample Input

    3
    2
    1 3
    2
    2
    1 3
    3
    4
    5 2 1 4
    11

    Sample Output

    No
    Yes
    Yes

    Hint

    The possible huffman codes for examples:

    None
    '1', '0'
    '1', '001', '000', '01'
    
    • 1
    • 2
    • 3

    🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨🧨
    🔑思路

    bitset+优先队列

    💯CODE代码:

    #include 
    using namespace std ;
    int n , E ;
    int t , x , y ;
    priority_queue < int > q ;
    bitset < 499600 > w ;
    int main () {
        cin >> t ;
        while (t -- ) {
            cin >> n ;
            while (! q.empty ())
                q.pop () ;
            while (n -- ) {
                cin >> x ;
                q.push (- x) ;
            }
            cin >> E ;
            if (E > 499600) {
                puts ("No") ;
                continue ;
            }
            w.reset () ;
            w.set (0) ;
            while (q.size () > 1) {
                x = q.top () ;
                q.pop () ;
                y = q.top () ;
                q.pop () ;
                q.push (x + y) ;
                x = - x , y = - y ;
                w = (w << x) | (w << y) ;
            } cout << (w.test (E) ? "Yes" : "No") << endl ;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    关于asio2项目example目录中的几个tcp示例的说明
    对OSI 7层模型的理解
    各位帅哥美女们,请问下面这种情况怎么解决呀,网上很多方法我都试过了,都没用
    为什么建议框架源码学习从Mybatis开始?能说这么清楚的,少见了
    在 JavaScript 中检查 2 个数组是否相等的简单方法
    孤举者难起,众行者易趋,openGauss 5.1.0版本正式发布!
    C#实现在企业微信内创建微信群发送群消息
    CentOS 7 Jenkins配置及SpringBoot项目自动部署
    C#【必备技能篇】Hex文件转bin文件的代码实现
    LeetCode【28. 找出字符串中第一个匹配项的下标】
  • 原文地址:https://blog.csdn.net/m0_60519493/article/details/126342151