典型的DAG(有向无环图)最长路模型。本来是DP[a][b],a,b分别表示长和宽,数组存自身加上面最多还能叠多高,但是a,b可能很大,不能开那么大的数组。所以需要转换一下,把立方体的长宽转换为它们的排序,高不用转换。这里利用了set中元素不会重复并自动排序的特性。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000
using namespace std;
//转换前
struct block{
int x;
int y;
int z;
};
block B[40];
//转换后
struct rect{
int a;
int b;
int h;
};
rect R[100];
int N;
int dp[100][100];
int fun(int s){
int a=R[s].a;int b=R[s].b;
if(dp[a][b]!=-1)return dp[a][b];
int re=0;
for(int i=1;i<=N*3;i++){
if( (R[i].a<a&&R[i].b<b)||(R[i].b<a&&R[i].a<b) )re=max(re,fun(i));
}
re+=R[s].h;
dp[a][b]=dp[b][a]=re;
return re;
}
set<int> rank;
int main(){
int _case=0;
while(cin>>N){
if(!N)break;
memset(dp,-1,sizeof(dp));
rank.clear();
for(int i=1;i<=N;i++){
cin>>B[i].x>>B[i].y>>B[i].z;
rank.insert(B[i].x);
rank.insert(B[i].y);
rank.insert(B[i].z);
}
for(int i=1;i<=N;i++){
//找rank
int rankx,ranky,rankz;
int count=0;
for(set<int>::iterator it=rank.begin();it!=rank.end();it++){
count++;
if(*it==B[i].x)rankx=count;
if(*it==B[i].y)ranky=count;
if(*it==B[i].z)rankz=count;
}
//长宽转化为相应的rank
R[i*3-2].a=rankx;R[i*3-2].b=ranky;R[i*3-2].h=B[i].z;
R[i*3-1].a=ranky;R[i*3-1].b=rankz;R[i*3-1].h=B[i].x;
R[i*3].a=rankz;R[i*3].b=rankx;R[i*3].h=B[i].y;
}
int _max=0;
for(int i=1;i<=N*3;i++){
_max=max(fun(i),_max);
}
_case++;
printf("Case %d: maximum height = %d\n",_case,_max);
}
return 0;
}
本文详细介绍了如何使用排序优化技术解决DAG(有向无环图)最长路径问题,并通过实例展示了从原始数据到最终最优路径求解的过程。包括数据结构转换、动态规划的应用、以及复杂性的优化策略。
939

被折叠的 条评论
为什么被折叠?



