Uva 1072 Huffman Codes 题解

Uva 1072 Huffman Codes 题解

一个需要技巧的爆搜。

/*
{
######################
#       Author       #
#        Gary        #
#        2020        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
int n;
int answer=0;
int fa[55];
int val[55];
int N=0;
int is[22];
int label[55];
int son[55][2];
int oldson[55][2];
void dfs(int now,int rest,int have=1){
	if(now==N+1){
		answer++;
		return ;
	}
	if(son[now][0]){
		val[now]=val[son[now][0]]+val[son[now][1]];
		if(val[now]<val[now-1]) return;
		dfs(now+1,rest,have);
	}
	else{
		rb(i,max(1,val[now-1]),rest){
			if(have==n){
				i=rest;
			}
			val[now]=i;
			if(i*(n-have)<=(rest-i))
				dfs(now+1,rest-i,have+1);
		}
	}
}
int insert(string & s,int pos,int now=0){
	if(pos==s.length()) return now;
	if(s[pos]=='0'){
		if(!son[now][0]) son[now][0]=++N,fa[N]=now;
		return insert(s,pos+1,son[now][0]);
	}
	if(!son[now][1]) son[now][1]=++N,fa[N]=now;
	return insert(s,pos+1,son[now][1]);
}
void Label(int now,int depth,int target){
	if(target==depth){
		label[now]=++N;
		return ;
	}
	if(son[now][0]){
		Label(son[now][0],depth+1,target);
	} 
	if(son[now][1]){
		Label(son[now][1],depth+1,target);
	}
}
bool cmp(int A,int B){
	return label[A]<label[B];
}
int main(){
	int T=0;
	while(true){
		N=0;
		memset(son,0,sizeof(son));
		memset(val,0,sizeof(val));
		scanf("%d",&n);
		if(!n) break;
		rb(i,1,n){
			string s;
			cin>>s;
			is[i]=insert(s,0);
		}	
		N=0;
		rl(i,n+2,1){
			Label(0,1,i);
		}
		sort(is+1,is+1+n,cmp);
		answer=0;
		rb(i,0,N-1) oldson[i][0]=son[i][0],oldson[i][1]=son[i][1];
		rb(i,0,N-1){
			if(oldson[i][0])
				son[label[i]][0]=label[oldson[i][0]];
			else son[label[i]][0]=0;
			if(oldson[i][1])
				son[label[i]][1]=label[oldson[i][1]];
			else son[label[i]][1]=0;
		}
		dfs(1,100);
		printf("Case %d: %d
",++T,answer);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/gary-2005/p/14140764.html