• 01背包 ZOJ 3931 Exact Compression


    题目连接

    题意:n个数字构建哈夫曼树,问是否存在这样一棵树使得:(Fi数字大小,Ci哈夫曼表示下,'0'的数量)

    分析:每次从优先队列取出两个数字可以互换位置,这样可以01互换。设a[i] <= b[i],a[i]为左儿子,b[i]为右儿子,如果加上a[i],表示累加上了a[i]下的所有点在i的位置的0的贡献,如果加上b[i]-a[i]就表示左右互换。所以可以转换为01背包问题换不换的问题,考虑到E很大,初始化为E’=E-,表示从最小的可能值到所求E的累加值E',然后对E‘进行dp

    #include <bits/stdc++.h>
    
    const int S = 128 + 5;
    const int N = 128000 + 5;
    int a[S], b[S];
    int dp[N];
    
    int main() {
        int T; scanf ("%d", &T);
        while (T--) {
            int n; scanf ("%d", &n);
            std::priority_queue<int, std::vector<int>, std::greater<int> > pque;
            for (int x, i=0; i<n; ++i) {
                scanf ("%d", &x);
                pque.push (x);
            }
            int E, sum = 0; scanf ("%d", &E);
            for (int i=1; i<n; ++i) {
                int fir = pque.top (); pque.pop ();
                int sec = pque.top (); pque.pop ();
                if (fir > sec) {
                    std::swap (fir, sec);
                }
                a[i] = fir; b[i] = sec;
                E -= a[i]; sum += b[i] - a[i];
                pque.push (fir + sec);
            }
            if (E < 0 || E > sum) {
                puts ("No");
                continue;
            }
            std::fill (dp, dp+1+E, 0);
            dp[0] = 1;
            for (int i=1; i<n; ++i) {
                int dif = b[i] - a[i];
                for (int j=E; j>=dif; --j) {
                    if (dp[j-dif]) {
                        dp[j] = 1;
                    }
                }
            }
            if (dp[E]) {
                puts ("Yes");
            } else {
                puts ("No");
            }
        }
    
        return 0;
    }
    

    还有bitset的暴力写法,<< 运算相当于加,参考博文

  • 相关阅读:
    python--输出spwm的数组
    爬虫二:爬取糗事百科段子
    爬虫一:爬取信息
    Python中的切片操作
    JSON
    python 中的异常处理与种类
    register的功能
    static的功能
    网络安全的认识
    VMware5.5-vCenter Converter(转换)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5392324.html
Copyright © 2020-2023  润新知