1. 程式人生 > >NOI 2015 荷馬史詩 題解&程式碼

NOI 2015 荷馬史詩 題解&程式碼

對於一些不同的單詞,每個單詞會給出一個出現頻率
對於每個單詞,給它一個唯一的字串型的編號【不是其它字串型編號的字首】
其實是個貪心【噗】,按照哈弗曼樹的形式將出現頻率與編碼長度反序排列…就好了

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