NOI 2015 荷馬史詩 題解&程式碼
阿新 • • 發佈:2019-02-11
對於一些不同的單詞,每個單詞會給出一個出現頻率
對於每個單詞,給它一個唯一的字串型的編號【不是其它字串型編號的字首】
其實是個貪心【噗】,按照哈弗曼樹的形式將出現頻率與編碼長度反序排列…就好了
#include<iostream>
#include<queue>
#include<stdio.h>
using namespace std;
struct node{
long long id,len;
long long sum;
}temp;
bool operator<(node a,node b)
{
if(a.sum>b.sum)return true;
if(a.sum<b.sum)return false;
return a.len>b.len;
}
priority_queue <node> q;
long long n,k,tot;
long long s,ans,w[100005],fa[200005][15];
void dfs(int x)
{
if(x<=n)return;
for(int i=0;i<k;i++)
{
fa[fa[x][i]][k]+=fa[x][k];
dfs(fa[x][i]);
}
}
int main(void )
{
cin>>n>>k;
temp.len=0;
for(int i=1;i<=n;i++)
{
cin>>w[i];
fa[i][k]=1;
temp.id=i;
temp.sum=w[i];
q.push(temp);
}
if(k!=2)
while(n%(k-1)!=1)
{
n++;
temp.id=n;
temp.sum=0;
fa[n][k]=1 ;
q.push(temp);
}
tot=n+1;
while(!q.empty())
{
temp.sum=0LL;
temp.id=tot++;
temp.len=0;
for(int i=0;i<k;i++)
{
temp.len=max((q.top()).len+1,temp.len);
temp.sum+=q.top().sum;
fa[temp.id][i]=(q.top()).id;
q.pop();
}
if(q.empty())break;
fa[temp.id][k]=1;
q.push(temp);
}
dfs(tot-1);
for(int i=1;i<=n;i++)
{
s+=fa[i][k]*w[i];
ans=max(ans,fa[i][k]);
}
cout<<s<<endl<<ans<<endl;
return 0;
}