uva 437 The Tower of Babylon

题意:有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
",ans);
}

int main(){
    int cas=1;
    while(read()){
        printf("Case %d: maximum height = ",cas++);
        solve();
    }
    return 0;
}
View Code


下面是刘汝佳的代码

// 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
", ++kase, ans);
  }
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/jihe/p/5223599.html