标签:
题意:有n个立方体,要堆成一个尽量高的主子,每个立方体上面放的立方体的长宽都严格小于下面,每个立方体有无限个
分析:我的做法是,每个立方体最多有6种状态,那么也就拥有6n个固定长宽高的立方体,那么这就是一个DAG上的最长路,6n个正方体,O(n^2)的算法,
很简单,详情见代码
#include<bits/stdc++.h> using namespace std; const int maxn=205; int m,n,dp[maxn]; struct node{ int x,y,z; void init(int a,int b,int c){ x=a;y=b;z=c; } }p[maxn]; bool cmp(node a,node b){ return a.x*a.y<b.x*b.y; } bool read(){ scanf("%d",&n); if(!n) return false; m=0; while(n--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); p[m++].init(a,b,c); p[m++].init(b,a,c); p[m++].init(a,c,b); p[m++].init(b,c,a); p[m++].init(c,a,b); p[m++].init(c,b,a); } sort(p,p+m,cmp); return true; } void solve(){ int ans=0; for(int i=0;i<m;i++){ dp[i]=p[i].z; for(int j=0;j<i;j++) if(p[i].x>p[j].x&&p[i].y>p[j].y) dp[i]=max(dp[i],dp[j]+p[i].z); ans=max(ans,dp[i]); } printf("%d\n",ans); } int main(){ int cas=1; while(read()){ printf("Case %d: maximum height = ",cas++); solve(); } return 0; }
下面是刘汝佳的代码
// UVa437 The Tower of Babylon // Rujia Liu // 算法:DAG上的最长路,状态为(idx, k),即当前顶面为立方体idx,其中第k条边(排序后)为高 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define REP(i,n) for(int i = 0; i < (n); i++) const int maxn = 30 + 5; int n, blocks[maxn][3], d[maxn][3]; void get_dimensions(int* v, int b, int dim) { int idx = 0; REP(i,3) if(i != dim) v[idx++] = blocks[b][i]; } int dp(int i, int j) { int& ans = d[i][j]; if(ans > 0) return ans; ans = 0; int v[2], v2[2]; get_dimensions(v, i, j); REP(a,n) REP(b,3) { get_dimensions(v2, a, b); if(v2[0] < v[0] && v2[1] < v[1]) ans = max(ans, dp(a,b)); } ans += blocks[i][j]; return ans; } int main() { int kase = 0; while(scanf("%d", &n) == 1 && n) { REP(i,n) { REP(j,3) scanf("%d", &blocks[i][j]); sort(blocks[i], blocks[i]+3); } memset(d, 0, sizeof(d)); int ans = 0; REP(i,n) REP(j,3) ans = max(ans, dp(i,j)); printf("Case %d: maximum height = %d\n", ++kase, ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jihe/p/5223599.html