hdu 4001今天网络赛的题目。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//dp[i]表示以第i个长方体结尾的最大高度(先排好序的)
//虽说不难,但一些细节能让人崩溃,以后一定要注意
//刚开始想到的状态为前i个长方体所能产生的最大高度,但亲注意:
//ps:这是比赛时想到的状态,悲剧就是这么发生的
//如果dp[i]如上定义,那么当用第i个长方体往前覆盖时,应该在原来的路径上覆盖,而不是从i-1->1;
//因此这种方法正确性貌似有待证明
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
__int64 dp[1050];
struct node{
__int64 x,y,z,flag;
}a[1050];
int cmp ( node a,node b)
{
if(a.x==b.x)
{
if(a.y==b.y)
return a.flag>b.flag;//细节1:x和y相同时,flag越小,覆盖前一个长方体的机会就越大
return a.y<b.y;
}
return a.x<b.x;
}
int main()
{
__int64 n,i,j;
while(scanf("%I64d",&n),n)
{
for(i=1;i<=n;i++)
{
scanf("%I64d%I64d%I64d%I64d",&a[i].x,&a[i].y,&a[i].z,&a[i].flag);
if(a[i].x<a[i].y)//细节2
{
int temp=a[i].x;
a[i].x=a[i].y;
a[i].y=temp;
}
}
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;i++)
dp[i]=a[i].z;
for(i=2;i<=n;i++)
{
//printf("i=%I64d z=%I64d\n",i,a[i].z);
//开始一直悲剧地把for循环写在外面,就一直错,一直错。。。。
if(a[i].flag==0)
{
for(j=1;j<i;j++)
{
if(a[i].x>=a[j].x&&a[i].y>=a[j].y&&dp[j]+a[i].z>dp[i])
dp[i]=dp[j]+a[i].z;//能更新就更新,下同。
}
}
else if(a[i].flag==1)
{
for(j=1;j<i;j++)
{
if(a[i].x>=a[j].x&&a[i].y>=a[j].y&&a[i].x*a[i].y>a[j].x*a[j].y&&dp[j]+a[i].z>dp[i])//细节3:关键地方阅读要仔细,相乘会超int
dp[i]=dp[j]+a[i].z;
}
}
else
{
for(j=1;j<i;j++)
{
if(a[i].x>a[j].x&&a[i].y>a[j].y&&dp[j]+a[i].z>dp[i])
dp[i]=dp[j]+a[i].z;
}
}
}
__int64 ans=dp[1];
for(i=2;i<=n;i++)
{
if(ans<dp[i])
ans=dp[i];
}
printf("%I64d\n",ans);
}
return 0;
}
总结就是:我就是菜鸟!!