0
点赞
收藏
分享

微信扫一扫

Monkey and Banana HDU - 1069

秀妮_5519 2022-06-15 阅读 38

​​点击打开链接​​

两种解法

 

一:

将每个立方体的的三个状态(分别以三个面为底)单独抽象为三个立方体 这样存立方体的数组最多开90即可 记为num

dp[i][j]代表在第i层放第j个立方体是总高度为多少

状态方程为dp[i][j]=max{dp[i-1][k],1<=k<=num}

这个方程看起来很黄很暴力 要跑三层循环 但是题目数据量很小

最外层循环i是层数 i最多不会超过90 因为每个立方体抽象出来的三个状态最多只能用一次 因为提议要求严格递减(不止面积要严格小于 而且对应长宽也要考虑 详见代码)

而内两层循环不超过90*90 是枚举这一层要放哪个立方体(抽象状态) 而在这一层放这个立方体的条件下 再枚举上一层放哪个立方体才能保证既可以放的下又有最大高

还有就是各种边界处理很麻烦 尤其是上下两层矩形的长宽是否符合条件的判断

 

#include <stdio.h>
#include <cstring>
#define N 99999999
using namespace std;

struct node
{
int x;
int y;
int h;
};

node cube[91];
int dp[101][91];
int book[101][91];
int n,num;

int judge(int a,int b,int c,int d)
{
int aa,bb,cc,dd;
if(a<b) aa=a,bb=b;
else aa=b,bb=a;
if(c<d) cc=c,dd=d;
else cc=d,dd=c;
if(aa>cc||bb>dd) return 0;
else if(aa==cc||bb==dd) return 0;
else return 1;
}

int main()
{
int i,j,k,a,b,c,cnt,maxx,flag,ans;
cnt=1;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
num=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
num++;
cube[num].x=a,cube[num].y=b,cube[num].h=c;
num++;
cube[num].x=a,cube[num].y=c,cube[num].h=b;
num++;
cube[num].x=b,cube[num].y=c,cube[num].h=a;
}
memset(dp,0,sizeof(int));
memset(book,0,sizeof(int));
ans=0;
for(i=1;i<=100;i++)
{
flag=0;
if(i==1)
{
flag=1;
for(j=1;j<=num;j++)
{
dp[i][j]=cube[j].h;
book[i][j]=j;
}
continue;
}
for(j=1;j<=num;j++)
{
maxx=-1;
for(k=1;k<=num;k++)
{
if(dp[i-1][k]==N)continue;
if(judge(cube[j].x,cube[j].y,cube[book[i-1][k]].x,cube[book[i-1][k]].y)==1)
{
if(dp[i-1][k]>maxx)
{
maxx=dp[i-1][k];
}
}
}
if(maxx==-1)
{
dp[i][j]=N;
book[i][j]=-1;
}
else
{
flag=1;
dp[i][j]=maxx+cube[j].h;
book[i][j]=j;
if(dp[i][j]>ans) ans=dp[i][j];
}
}
if(flag==0) break;
}
printf("Case %d: maximum height = %d\n",cnt++,ans);
}
return 0;
}

 

二:

第j个箱子能给第i个箱子垫底 当且仅当min(box[j].x,box[j].y)<min(box[i].x,box[i].y)&&max(box[j].x,box[j].y)<max(box[i].x,box[i].y)

当对所有箱子按x排序之后 能给第i个箱子垫底的箱子全都在[1,i-1]中 从中选一个最大的即可 而[i+1,n]范围内的箱子都没法垫底 满足无后效性

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100;

struct node
{
int x,y,z;
};

node box[maxn];
int dp[maxn];
int n;

bool cmp(node n1,node n2)
{
return n1.x<n2.x;
}

int main()
{
int cas,i,j,x,y,z,maxx,ans;
cas=1;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
for(i=1;i<=n;i++){
scanf("%d%d%d",&x,&y,&z);
box[3*i-2].x=min(x,y),box[3*i-2].y=max(x,y),box[3*i-2].z=z;
box[3*i-1].x=min(x,z),box[3*i-1].y=max(x,z),box[3*i-1].z=y;
box[3*i].x=min(y,z),box[3*i].y=max(y,z),box[3*i].z=x;
}
sort(box+1,box+3*n+1,cmp);
ans=0;
for(i=1;i<=3*n;i++){
maxx=0;
for(j=1;j<=i-1;j++){
if(min(box[j].x,box[j].y)<min(box[i].x,box[i].y)&&max(box[j].x,box[j].y)<max(box[i].x,box[i].y)){
maxx=max(maxx,dp[j]);
}
}
dp[i]=maxx+box[j].z;
ans=max(ans,dp[i]);
}
printf("Case %d: maximum height = %d\n",cas++,ans);
}
return 0;
}

 

 

 

 

 

 


举报

相关推荐

0 条评论