【DFS】【拓撲排序】【動態規劃】Gym - 100642A - Babs' Box Boutique
阿新 • • 發佈:2017-08-17
關鍵字 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