解题报告:
各种错误,各种纠正。。自我感觉对DP的理解入门些了。
第一种思路是从i结点出发所能达到的最大高度,状态转移方程为dp[i] = dim[i]+max{dp[j]}, 其中G[i][j]=1,即j能放在i上。
AC代码如下:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 91 struct{ int x, y, z; }dim[MAXN*3]; int dp[MAXN], G[MAXN][MAXN], _index; void _swap(int *a, int *b){ int t = *a; *a = *b; *b = t; } void _sort(int *a, int *b, int *c){ if(*a > *b) _swap(a, b); if(*a > *c) _swap(a, c); if(*b > *c) _swap(b, c); } int _max(int a, int b){ return a > b ? a : b; } void _assi(int a, int b, int c){ dim[_index].x = a; dim[_index].y = b; dim[_index++].z = c; } int d(int i){ if(dp[i] > 0) return dp[i]; int j; for(j=1; j<_index; j++){ if(G[i][j]) dp[i] = _max(dp[i], d(j)); } dp[i] += dim[i].z; return dp[i]; } int main(){ int cnt, n, i, j, x, y, z; cnt = 0; while(scanf("%d", &n) == 1 &&n != 0){ _index = 1; cnt++; memset(G, 0, sizeof(G)); memset(dp, 0, sizeof(dp)); for(i=1; i<=n; i++){ scanf("%d %d %d", &x, &y, &z); _sort(&x, &y, &z); _assi(x, y, z); if(z != y) _assi(x, z, y); //这里赋值的同时去掉重复的。当然也可以不去。 if(x != y) _assi(y, z, x); } for(i=1; i<_index; i++){ for(j=1; j<_index; j++){ if(dim[i].x > dim[j].x && dim[i].y > dim[j].y) G[i][j] = 1; } } for(i=1; i<_index; i++) dp[i] = d(i); int ans = 0; for(i=1; i<_index; i++) if(ans < dp[i]) ans = dp[i]; printf("Case %d: maximum height = %d\n", cnt, ans); } return 0; }
第二种是从到i结点所能达到的最大高度,状态转移方程为dp[i] = dim[i]+max{dp[j]}, 其中G[j][i] = 1,即i能放在j上。
首先,让在输入数据的时候要保证结构体中的x>=y,然后再对这些数据进行排序,如果两者之间的x相等, 就进行y的二级排序。如此就能保证能够盛放i的长方体如果存在的话那么一定在dim[0 ~ i-1]中。省去了G这个二维数组。
AC代码如下。
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 91 struct Dim{ int x, y, z; }dim[MAXN*3]; int dp[MAXN], _index; int _max(int a, int b){ return a > b ? a : b; } void _assi(int a, int b, int c){ dim[_index].x = a > b ? a : b; dim[_index].y = a > b ? b : a; dim[_index++].z = c; } int cmp(const struct Dim *a, const struct Dim *b){ //竟然能这么用。。 if(a->x != b->x) return b->x - a->x; else return b->y - a->y; } int main(){ int cnt, n, i, j, x, y, z, ans; cnt = 0; while(scanf("%d", &n) == 1 &&n != 0){ _index = 0; cnt++; memset(dp, 0, sizeof(dp)); for(i=0; i<n; i++){ scanf("%d %d %d", &x, &y, &z); _assi(x, y, z); //这里没有排除3个数存在2个或者3个有重复数字的情况,不过不影响 _assi(x, z, y); _assi(y, z, x); } qsort(dim, _index, sizeof(dim[0]), cmp); dp[0] = dim[0].z; for(i=1; i<_index; i++){ //dp ans = 0; for(j=i-1; j>=0; j--){ if(dim[j].x > dim[i].x && dim[j].y >dim[i].y) if(ans < dp[j]) ans = dp[j]; } dp[i] = ans+dim[i].z; } ans = 0; for(i=0; i<_index; i++) if(ans < dp[i]) ans = dp[i]; printf("Case %d: maximum height = %d\n", cnt, ans); } return 0; }