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;
}