Description
给定一个数字N,代表有N种不同的字符,已知每种字符的出现次数,现在要求你设计一种编码,使得任意一个编码都不是另外一个编码的前缀,并且使得这些字符经过编码压缩之后的总长度最小;
Input
一个数字N 代表有多少种不同的字符(0<=N<=1000)N个数字 每个数字代表一种字符的出现次数
Output
一个数字,代表总的编码长度
Sample Input
5 1 2 3 4 5 3 3 8 8
Sample Output
33 30
正常版
#include<bits/stdc++.h>
using namespace std;
bool bj[2001];
struct jg{
int l,r,q;
};
struct nsj
{
int n1,n2;
};
int data[2001],cd[2001];
jg shu[2001];
void dfs(int x,int y);
nsj zhapy(int x);
int main()
{
int n,i,cnt;
nsj n12;
while(cin>>n)
{
memset(cd,0,sizeof(cd));
memset(shu,0,sizeof(shu));
for(i=1;i<=n;i++)
{
cin>>data[i];
}
for(i=1;i<=n;i++)
{
bj[i]=true;
bj[i+n]=false;
}
cnt=n;
while(cnt<2*n-1)
{
n12=zhapy(cnt);
bj[n12.n1]=bj[n12.n2]=false;
cnt++;
bj[cnt]=true;
shu[cnt].l=n12.n1;
shu[cnt].r=n12.n2;
shu[cnt].q=data[n12.n1]+data[n12.n2];
data[cnt]=data[n12.n1]+data[n12.n2];
}
dfs(2*n-1,0);
int ans=0;
for(i=1;i<=n;i++)
{
ans+=cd[i]*data[i];
}
cout<<ans<<endl;
}
return 0;
}
nsj zhapy(int x)
{
nsj cnt;
int x1,x2,i;
x1=999999999;
x2=999999999;
cnt.n1=1;
cnt.n2=1;
for(i=1;i<=x;i++)
{
if(bj[i])
{
if(data[i]<x1)
{
x2=x1;
cnt.n2=cnt.n1;
x1=data[i];
cnt.n1=i;
}
else if(data[i]<x2)
{
cnt.n2=i;
x2=data[i];
}
}
}
return cnt;
}
void dfs(int x,int y)
{
int l,r;
l=shu[x].l;
if(l!=0)
{
dfs(l,y+1);
r=shu[x].r;
dfs(r,y+1);
}
else
{
cd[x]=y;
}
}
变态版:
#include<bits/stdc++.h>
using namespace std;bool bj[2001];struct jg{int l,r,q;};struct nsj{int n1,n2;};int data[2001],cd[2001];jg shu[2001];void dfs(int x,int y);nsj zhapy(int x);int main(){int n,i,cnt;nsj n12;while(cin>>n){memset(cd,0,sizeof(cd));memset(shu,0,sizeof(shu));for(i=1;i<=n;i++){cin>>data[i];}for(i=1;i<=n;i++){bj[i]=true;bj[i+n]=false;}cnt=n;while(cnt<2*n-1){n12=zhapy(cnt);bj[n12.n1]=bj[n12.n2]=false;cnt++;bj[cnt]=true;shu[cnt].l=n12.n1;shu[cnt].r=n12.n2;shu[cnt].q=data[n12.n1]+data[n12.n2];data[cnt]=data[n12.n1]+data[n12.n2];}dfs(2*n-1,0);int ans=0;for(i=1;i<=n;i++){ans+=cd[i]*data[i];}cout<<ans<<endl;}return 0;}nsj zhapy(int x){nsj cnt;int x1,x2,i;x1=999999999;x2=999999999;cnt.n1=1;cnt.n2=1;for(i=1;i<=x;i++){if(bj[i]){if(data[i]<x1){x2=x1;cnt.n2=cnt.n1;x1=data[i];cnt.n1=i;}else if(data[i]<x2){cnt.n2=i;x2=data[i];}}}return cnt;}void dfs(int x,int y){int l,r;l=shu[x].l;if(l!=0){dfs(l,y+1);r=shu[x].r;dfs(r,y+1);}else{cd[x]=y;}}