今天终于开始刷dp的题目了!题目大意:给出n种长方体和各自边长,每种长方体选择数量没有限制,放在上面的长方体要小于下面的长方体,问能够放多高。
做法:每个长方体有三种摆放方式,把三种方式各看成一种长方体,把它们先按两条边长由大到小排序,然后枚举每个长方体,看能否放置在它之前的长方体下面,若能,记录其中最高的一种。
状态:dp[i] 表示以 第i 个长方体为底所能搭的最大高度。
转移方程: dp[i]=max{dp[i],dp[j]+b[i].h}
以下为代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int ret;
struct bnode
{
int x,y,h;
}b[100];
void addb(int xi,int yi,int hi)
{
b[ret].x=max(xi,yi);
b[ret].y=min(xi,yi);
b[ret].h=hi;
ret++;
}
bool cmp(bnode a,bnode b) //按长、宽由大到小排序
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
bool check(bnode a,bnode b)
{
return a.x>b.x && a.y>b.y;
}
int main()
{
// freopen("in.txt","r",stdin);
int n,t=1;
while(1){
scanf("%d",&n);
if(!n)break;
ret=0;
memset(b,0,sizeof(b));
for(int i=0;i<n;i++){
int xi,yi,zi;
scanf("%d%d%d",&xi,&yi,&zi);
addb(xi,yi,zi); addb(xi,zi,yi); addb(zi,yi,xi);
}
sort(b,b+3*n,cmp);
int dp[100];
memset(dp,0,sizeof(dp));
for(int i=0;i<3*n;i++) dp[i]=b[i].h;
for(int i=1;i<3*n;i++)
for(int j=0;j<i;j++){
if(check(b[i],b[j])){
dp[i]=max(dp[i],dp[j]+b[i].h); //状态转移
}
}
int maxx=0;
for(int i=0;i<3*n;i++) maxx=max(maxx,dp[i]);
printf("Case %d: maximum height = %d\n",t++,maxx);
}
return 0;
}