1. 程式人生 > >【DFS】【拓撲排序】【動態規劃】Gym - 100642A - Babs' Box Boutique

【DFS】【拓撲排序】【動態規劃】Gym - 100642A - Babs' Box Boutique

關鍵字 dag 在一起 ems class std rst ++i box

給你10個箱子,有長寬高,每個箱子你可以決定哪個面朝上擺。把它們摞在一起,邊必須平行,上面的不能突出來,問你最多擺幾個箱子。

3^10枚舉箱子用哪個面。然後按長為第一關鍵字,寬為第二關鍵字,從大到小排序。

如果前面的寬大於等於後面的寬,就連接一條邊。

形成一張DAG,拓撲排序後跑最長路即可。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int v[205],next[205],first[15],e;
void AddEdge(int U,int V){
	v[++e]=V;
	next[e]=first[U];
	first[U]=e;
}
typedef pair<int,int> Point;
Point d[15];
int ans;
int a[15],b[15],c[15],cho[15],ru[15],f[15],n;
bool cmp(const Point &a,const Point &b){
	return a.first!=b.first ? a.first>b.first : a.second>b.second;
}
void work(){
	for(int i=1;i<=n;++i){
		if(cho[i]==1){
			d[i]=make_pair(max(a[i],b[i]),min(a[i],b[i]));
		}
		else if(cho[i]==2){
			d[i]=make_pair(max(b[i],c[i]),min(b[i],c[i]));
		}
		else{
			d[i]=make_pair(max(c[i],a[i]),min(c[i],a[i]));
		}
	}
	e=0;
	memset(first,0,sizeof(first));
	memset(f,0,sizeof(f));
	memset(ru,0,sizeof(ru));
	sort(d+1,d+n+1,cmp);
	for(int i=1;i<=n;++i){
		for(int j=i+1;j<=n;++j){
			if(d[j].second<=d[i].second){
				AddEdge(i,j);
				++ru[j];
			}
		}
	}
	queue<int>q;
	for(int i=1;i<=n;++i){
		if(!ru[i]){
			q.push(i);
		}
	}
	while(!q.empty()){
		int U=q.front(); q.pop();
		for(int i=first[U];i;i=next[i]){
			f[v[i]]=max(f[U]+1,f[v[i]]);
			--ru[v[i]];
			if(!ru[v[i]]){
				q.push(v[i]);
			}
		}
	}
	ans=max(ans,1+(*max_element(f+1,f+n+1)));
}
void dfs(int cur){
	if(cur>n){
		work();
		return;
	}
	for(int i=1;i<=3;++i){
		cho[cur]=i;
		dfs(cur+1);
	}
}
int main(){
	int zu=0;
	while(1){
		++zu;
		scanf("%d",&n);
		if(n==0){
			return 0;
		}
		for(int i=1;i<=n;++i){
			scanf("%d%d%d",&a[i],&b[i],&c[i]);
		}
		ans=0;
		dfs(1);
		printf("Case %d: %d\n",zu,ans);
	}
	return 0;
}

【DFS】【拓撲排序】【動態規劃】Gym - 100642A - Babs' Box Boutique