题目大意就是给你一个字符串,把每个字母出现的次数作为一个权值,然后我们就得到了一个序列,求由这个序列组成树的最短的带权路径长度,即最优二叉树。
属于典型的哈夫曼编码问题。
#include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #define INF 999999999 using namespace std; int main() { char str[100000]; int t,n,w[26]; cin>>t; while(t--) { scanf("%d%s",&n,str); int len=strlen(str); for(int i=0;i<26;i++) w[i]=0; for(int i=0;i<len;i++) w[str[i]-'a']++; for(int i=0;i<26;i++) if(w[i]==0) w[i]=INF; sort(w,w+26); for(int i=0;i<26;i++) if(w[i]==INF) { len=i; break; } int wt=0; if(len==1) wt=w[0]; for(int i=0;i<len-1;i++) { w[0]=w[0]+w[1]; w[1]=INF; wt+=w[0]; sort(w,w+len); } if(wt>n) puts("no"); else puts("yes"); } return 0; }