题意:
小孩子玩积木堆房子的情景:
每组测试数据第一行给出n,代表接下来有n块砖;
接下来n行,每行给出砖的长,宽,高,属性(a,b,c,d);
属性d:d=0:该砖的长度和宽度(a,b)要比垫在他下面的砖的长,广大或者相等;就是长>=长,宽>=宽
d=1:改砖的宽度和长度要比下面的砖的长度大或者相等,同时,该砖的宽度值和面积值要比下面的砖的面积值大;即长>=长,宽>=宽,面积>面积。也就是长>=长&&宽>=宽&&(长>长||宽>宽)
d=2:该砖的长度和宽度(a,b)要比垫在他下面的砖的长,广大(严格大于);长>长,宽>宽。
分析:
先按长、宽 从小到大排序,再按d值从大到小排序;
想一下,D值越大,即对大小堆叠的要求越严格,所以,当长和宽一样时,D值越大的放前面,D值小的仍可往上堆叠,如此,可趋于最优
之后按不同的d值做一个简单的DP,注意,长和宽可交换
还有总高度的可能会超过int,所以用了__int64
View Code
#include<iostream>
#include<algorithm>
using namespace std;
struct block
{
int a,b,c,d;
}bl[1001];
int n;
__int64 dp[1001],ans;
bool cmp(block e,block f)
{
if(e.a!=f.a) return e.a<f.a;
if(e.b!=f.b) return e.b<f.b;
return e.d>f.d;
}
int main()
{
while(scanf("%d",&n)==1&&n)
{
for(int i=1;i<=n;i++)
{
scanf("%d %d %d %d",&bl[i].a,&bl[i].b,&bl[i].c,&bl[i].d);
if(bl[i].a<bl[i].b) { int temp=bl[i].a;bl[i].a=bl[i].b;bl[i].b=temp;}
}
sort(bl+1,bl+n+1,cmp);
ans=0;
for(int i=1;i<=n;i++)
{
dp[i]=bl[i].c;
for(int j=1;j<i;j++)
{
if(bl[i].d==0&&bl[i].a>=bl[j].a&&bl[i].b>=bl[j].b)
dp[i]=max(dp[j]+bl[i].c,dp[i]);
if(bl[i].d==1&&bl[i].a>=bl[j].a&&bl[i].b>=bl[j].b&&(bl[i].a>bl[j].a||bl[i].b>bl[j].b))
dp[i]=max(dp[j]+bl[i].c,dp[i]);
if(bl[i].d==2&&bl[i].a>bl[j].a&&bl[i].b>bl[j].b)
dp[i]=max(dp[j]+bl[i].c,dp[i]);
}
if(dp[i]>ans)
ans=dp[i];
}
printf("%I64d\n",ans);
}
return 0;
}