题目地址:https://cn.vjudge.net/problem/HDU-1069
看了一下这个DP教程,受到启发来做这题,一开始solve函数是这么写的
int solve()
{
getpre();
memset(dp,0,sizeof(dp));
dp[0][0] = 0;
dp[0][1] = bl[0].c;
for(int i=1;i<n;i++){
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
if(pre[i]!=-1){
dp[i][1] = bl[i].c;
if(dp[pre[i]][1]<dp[pre[i]][0]){
int mx = 0;
for(int j=i-1;j>=0;j--){
if(dp[j][1]>mx&&bl[j].a>bl[i].a&&bl[j].b>bl[i].b)
mx = dp[j][1];
}
dp[i][1]+=mx;
}
else dp[i][1]+=dp[pre[i]][1];
}
else dp[i][1] = bl[i].c+dp[0][0];
}
return max(dp[n-1][0],dp[n-1][1]);
}
错了,错得离谱。
把dp数组输出出来以后意识到问题的关键出在我没有保证在使用dp[i-1][0]的时候,该数据对应的顶部长宽大于当前块的长宽。因为该排序方式有个问题,排在当前块前面的块有可能当前块无法放在上面。
然后我做出了对应的修改,当dp[pre[i]][1]<dp[pre[i]][0]时,从排在该块前面的块的对应dp数组中,找出长宽大于当前块且最大的。然后就AC啦。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 99999
using namespace std;
struct Block
{
int a,b,c;
bool operator<(const Block&d)const{
if(a>d.a) return true;
else if(a==d.a){
if(b>d.b) return true;
else if(b==d.b) return c>d.c;
else return false;
}
return false;
}
}bl[200];
int n;
int dp[200][2];
int pre[200];
void getpre()
{
memset(pre,-1,sizeof(pre));
for(int i=0;i<n;i++){
for(int j=i-1;j>=0;j--){
if(bl[i].a<bl[j].a&&bl[i].b<bl[j].b){
pre[i] = j;
break;
}
}
}
}
int solve()
{
getpre();
memset(dp,0,sizeof(dp));
dp[0][0] = 0;
dp[0][1] = bl[0].c;
for(int i=1;i<n;i++){
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
if(pre[i]!=-1){
dp[i][1] = bl[i].c;
if(dp[pre[i]][1]<dp[pre[i]][0]){
int mx = 0;
for(int j=i-1;j>=0;j--){
if(dp[j][1]>mx&&bl[j].a>bl[i].a&&bl[j].b>bl[i].b)
mx = dp[j][1];
}
dp[i][1]+=mx;
}
else dp[i][1]+=dp[pre[i]][1];
}
else dp[i][1] = bl[i].c+dp[0][0];
}
return max(dp[n-1][0],dp[n-1][1]);
}
int main()
{
int k=1;
while(~scanf("%d",&n)&&n){
for(int i=0;i<n;i++){
scanf("%d%d%d",&bl[6*i].a,&bl[6*i].b,&bl[6*i].c);
bl[6*i+1].a = bl[6*i].b;
bl[6*i+1].b = bl[6*i].a;
bl[6*i+1].c = bl[6*i].c;
bl[6*i+2].a = bl[6*i].a;
bl[6*i+2].b = bl[6*i].c;
bl[6*i+2].c = bl[6*i].b;
bl[6*i+3].a = bl[6*i].c;
bl[6*i+3].b = bl[6*i].a;
bl[6*i+3].c = bl[6*i].b;
bl[6*i+4].a = bl[6*i].c;
bl[6*i+4].b = bl[6*i].b;
bl[6*i+4].c = bl[6*i].a;
bl[6*i+5].a = bl[6*i].b;
bl[6*i+5].b = bl[6*i].c;
bl[6*i+5].c = bl[6*i].a;
}
n*=6;
sort(bl,bl+n);
printf("Case %d: maximum height = %d\n",k++,solve());
}
}