EOJ 1271 The Tower of Babylon
http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=1271
因为盒子的方向是任意定的,所以把盒子的三个方向都存下来在dp会方便很多
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 9 struct Node 10 { 11 int x, y, z; 12 }b[100]; 13 int n; 14 15 bool cmp(const Node &a, const Node &b) 16 { 17 return a.x > b.x; 18 } 19 20 int main() 21 { 22 int x, y, z, ans = 0, maxn; 23 int cnt = 1; 24 while (cin >> n && n) 25 { 26 int k = 0; 27 maxn = 0; 28 for (int i = 0; i < n; i++) 29 { 30 cin >> x >> y >> z; 31 b[k].x = min(x, y); 32 b[k].y = max(x, y); 33 b[k++].z = z; 34 b[k].x = min(y, z); 35 b[k].y = max(y, z); 36 b[k++].z = x; 37 b[k].x = min(x, z); 38 b[k].y = max(x, z); 39 b[k++].z = y; 40 } 41 sort(b, b + n * 3, cmp); 42 for (int i = 3 * n - 2; i >= 0; i--) 43 { 44 ans = 0; 45 for (int j = i + 1; j < 3 * n; j++) 46 if (b[j].x < b[i].x && b[j].y < b[i].y && b[j].z > ans) 47 ans = b[j].z; 48 b[i].z += ans; 49 if (b[i].z > maxn) 50 maxn = b[i].z; 51 } 52 cout << "Case " << cnt++ << ": maximum height = " << maxn << endl; 53 } 54 return 0; 55 }
奇解:
由于每个盒子可以访问多次且访问顺序任意,无后效性不明显,参阅网上题解,发现这一点可以由 floyd 完美解决!
1 #include<map> 2 #include<set> 3 #include<list> 4 #include<cmath> 5 #include<ctime> 6 #include<queue> 7 #include<stack> 8 #include<cctype> 9 #include<cstdio> 10 #include<string> 11 #include<vector> 12 #include<cstdlib> 13 #include<cstring> 14 #include<iostream> 15 #include<algorithm> 16 #define MAXN 10005 17 using namespace std; 18 19 typedef struct 20 { 21 int x, y, z; 22 }P; 23 P t[105]; 24 int m, n, ans; 25 int g[105][105]; 26 27 void add(int x, int y, int z) 28 { 29 t[++n].x = x; 30 t[n].y = y; 31 t[n].z = z; 32 } 33 34 int fit(int i, int j) 35 { 36 if(t[i].x>t[j].x && t[i].y>t[j].y 37 || t[i].y>t[j].x && t[i].x>t[j].y) 38 return 1; 39 return 0; 40 } 41 42 void floyd() 43 { 44 for(int k=0; k<=n; k++) 45 for(int i=0; i<=n; i++) 46 for(int j=0; j<=n; j++) 47 if(g[i][k] && g[k][j]){ 48 g[i][j] = max(g[i][j], g[i][k]+g[k][j]); 49 ans = max(ans, g[i][j]); 50 } 51 } 52 53 int main() 54 { 55 int it=1; 56 while(scanf("%d", &m), m) 57 { 58 n = 0; 59 for(int i=1; i<=m; i++) 60 { 61 int x, y, z; 62 scanf("%d%d%d", &x, &y, &z); 63 add(x, y, z); //按高度分类 64 add(x, z, y); 65 add(y, z, x); 66 } 67 memset(g, 0, sizeof(g)); 68 for(int i=1; i<=n; i++) 69 g[0][i] = t[i].z; 70 for(int i=1; i<=n; i++) 71 for(int j=1; j<=n; j++) 72 if(fit(i, j)) 73 g[i][j] = t[j].z; //建图 74 ans = 0; 75 floyd(); 76 77 printf("Case %d: maximum height = %d\n", it++, ans); 78 } 79 }