Case 4: maximum height = 342
分析 : DAG最长路算法
状态总数O(n) 每个状态决策O(n) 时间复杂度O(n^2)
#include
#include
#include
#include
#define max(a,b) (a>b?a:b)
#define REP(i,n) for(int i = 0; i < (n) ; ++i)
const int maxn = 30 + 10 ;
int ra[maxn][3] , ans[maxn][maxn] ; // ra[i][k] i:长方形序号 , k: 高的序号
using namespace std;
int n ;
void get_rac( int* racn , int n , int k ) { // 引用指针
int num = 0 ;
REP( i , 3) {
if( k != i ) racn[num++] = ra[n][i] ; // 找到长宽 , 并存储
}
}
int dp( int i , int j ) {
int& Lmax = ans[i][j] ; // 引用ans[i][j]
if( Lmax > 0 ) return Lmax ; // 记忆化搜索
Lmax = 0 ;
int rac1[3] , rac2[3] ;
get_rac( rac1 , i , j ) ;
REP( ii , n ) {
REP( jj , 3) {
get_rac(rac2, ii , jj) ;
if( rac1[0] < rac2[0] && rac1[1] < rac2[1] ) // 严格小于
Lmax = max( Lmax, dp( ii, jj )+ra[ii][jj] ) ; // 这样写 , 整个函数返回值,不包含根节点 , 在主函数加上
}
} //也可写成Lmax= max (Lmax , dp(ii, jj)) ;循环外 Lmax += ra[i][j] ; return Lmax ;
// 因为 int& Lmax = ans[i][j] , 故不能写成 return Lmax + ra[i][j] ,ans[i][j]没改变 ;
// 这样写,函数递归完成包含根节点 ,主函数不必再加
return Lmax ;
}
int main() {
int text = 1 ;
while( ~scanf("%d",&n),n) {
memset(ans,0, sizeof(ans)) ;
REP(i,n) {
REP(j,3){
scanf("%d",&ra[i][j] ) ; // 存取三边分别作为高
}sort( ra[i], ra[i] + 3) ; // 边从小到大排序
}
int maxx = 0 ;
REP(i, n ) {
REP( j , 3 ) {
maxx = max(dp( i,j)+ra[i][j], maxx) ;
}
}
printf("Case %d: maximum height = %d\n",text++, maxx) ;
}
return 0 ;
}