题目链接:https://cn.vjudge.net/problem/HDU-1069
题意:有n种砖,每种砖有长宽高三个属性,每种砖有无限个,且砖可以旋转(即每种砖的长宽高可以相互对调),按照上面的砖的长与宽严格小于下面的砖的长与宽的放置方法,求最大的砖块累加高度。
思路:将每种砖(a,b,c)分解为六种砖(a,b,c),(b,a,c),(c,b,a),(c,a,b),(a,c,b),(b,c,a),然后按照长度排序,长度相同的按照宽排序,然后是高度,dp[i]代表当前顶部的砖块为i,由此可以得到状态转移方程:dp[i] = max(dp[i], dp[j] + heightofi),其中j为满足限制条件的砖块。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
struct dia
{
int a, b, c;
bool operator < (const dia A) const
{
if(a != A.a) return a > A.a;
else if(b != A.b) return b > A.b;
else return c > A.c;
}
}A[200];
int dp[200];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, a, b, c, pos = 0, id = 1;
while(cin>>n && n){
pos = 0;
for(int i = 0; i < n; ++i){
cin>>a>>b>>c;
A[++pos].a = a; A[pos].b = b; A[pos].c = c;
A[++pos].a = b; A[pos].b = a; A[pos].c = c;
A[++pos].a = c; A[pos].b = b; A[pos].c = a;
A[++pos].a = c; A[pos].b = a; A[pos].c = b;
A[++pos].a = a; A[pos].b = c; A[pos].c = b;
A[++pos].a = b; A[pos].b = c; A[pos].c = a;
}
sort(A+1,A+pos+1);
dp[0] = 0;
for(int i = 1; i <= pos; ++i){
dp[i] = A[i].c;
for(int j = 1; j < i; ++j){
if(A[j].a > A[i].a && A[j].b > A[i].b)
dp[i] = max(dp[i], dp[j] + A[i].c);
}
}
int ans = 0;
for(int i = 1; i <= pos; ++i)
ans = max(ans, dp[i]);
cout<<"Case "<<id++<<": maximum height = ";
cout<<ans<<'\n';
}
return 0;
}