这道动态规划的状态转移方程是比较好得到的:
如果该长方体i可以放在前面的长方体j上,dp[i]=max(dp[i],dp[j]+node[i].z)
如果不可以放在前面的长方体上面,就是dp[i]=node[i].z;
我是先将长方体按照长度排列顺序,如果长方体的长度相同的话然后将长方体按照宽度排列顺序。
当时卡在了往前遍历的时候,对于第i个长方体,我以为是只要从i-1个往前遍历,那么最先得到的就是唯一的j。其实前面可能还有j会使的h更大。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
const int maxn=200;
int dp[maxn];
struct Node{
int x,y,z;
bool operator<(const Node a)const{//换成按照长宽排序
if(max(this->x,this->y)!=max(a.x,a.y)){
return max(this->x,this->y) > max(a.x,a.y);
}else{
return min(this->x,this->y) > min(a.x,a.y);
}
}
}node[maxn];
bool isOK(Node a,Node b)
{
if(min(a.x,a.y)>min(b.x,b.y) && max(a.x,a.y)>max(b.x,b.y)){
return true;
}
else{
return false;
}
}
int main()
{
int T;
int cnt=0;
while(EOF!=scanf("%d",&T)&&T)
{
memset(dp,0,sizeof(dp));
int i,j,k,x,y,z;
for(i=0;i<T*3;i+=3){//将数据从大到小排列
scanf("%d %d %d",&x,&y,&z);
node[i].x=x;node[i].y=y;node[i].z=z;
node[i+1].x=y;node[i+1].y=z;node[i+1].z=x;
node[i+2].x=z;node[i+2].y=x;node[i+2].z=y;
}
sort(node,node+T*3);
dp[0]=node[0].z;
for(i=1;i<T*3;i++){
dp[i]=node[i].z;
//往前遍历找到合适面积的长方体
for(j=i-1;j>=0;j--){
if(isOK(node[j],node[i])){
dp[i]=max(dp[i],dp[j]+node[i].z);
}
}
}
cnt++;
cout << "Case " << cnt << ": maximum height = ";
int nowmaxh=0;
for(i=0;i<T*3;i++){
if(dp[i]>nowmaxh){
nowmaxh=dp[i];
}
}
cout << nowmaxh << endl;
}
return 0;
}
//
//cout << endl;
// for(i=0;i<T*3;i++){
// cout << dp[i] << ' ';
// }
// cout << endl;
// int n=0;
// for(i=0;i<T*3;i++){
// n++;
// cout <<n << " "<< max(node[i].x,node[i].y) << " "<<min(node[i].x,node[i].y) << " "<< node[i].z << endl;
// }