HDU 2527 Safe Or Unsafe (哈夫曼树)

Problem:http://acm.hdu.edu.cn/showproblem.php?pid=2527

 

 

/*
  节点之间的路径长度:
  (无权)若节点1的层数为1,节点2的层数是n,则节点1,2之间的路径长度为n-1;
  (带权)若节点1的层数为1,权值为a,节点2的层数是n,权值为b,则1的路径长度
  为a*(n-1),节点2的路径长度为b*(n-1);
  树的路径长度;
  (无权)从树的根节点到树的各个节点的路径长度之和
  (带权)带权路径长度等于所有叶子的带权路径长度之和=所有非叶子节点(包括根)的权值之和
  原因是:假如a是根节点,a-b,a-c,c-d,c-e,则叶子节点是b,d,e,则有b*1 + 2*d + 2*e;
  非叶子节点的权值和为a+c = b+c+d+e = b+2*d+2*e;
  
  所以此题要求的就是所有非叶子节点的值的和(所有叶子的带权路径之和)
  0MS	248K
  */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

int Case;
int m;
int vis[30];
char str[1005];

int main()
{
    scanf("%d",&Case);
    while(Case--)
    {
        scanf("%d",&m);
        scanf("%s",str);
        memset(vis,0,sizeof(vis));
        for(int i=0; i<(int)strlen(str); i++)
            vis[str[i]-'a'] ++;
        priority_queue < int,vector<int>,greater<int> > Q;
        for(int i=0; i<26; i++)
            if(vis[i])
                Q.push(vis[i]);
        if(Q.size() == 1)
        {
            int t = Q.top();
            if(t > m)
                printf("no\n");
            else
                printf("yes\n");
            continue;
        }
        int ans = 0;
        while(Q.size() >= 2)
        {
            int temp1 = Q.top();
            Q.pop();
            int temp2 = Q.top();
            Q.pop();
            int temp = temp1 + temp2;
            ans += temp;
            Q.push(temp);
        }
        if(ans > m)
            printf("no\n");
        else
            printf("yes\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值