解题思路:典型的带权DAG动态规划题目,每一个长方体可以分成三个节点,即3*n个节点符合面积覆盖要求的相互连接,连接长度为高度h,求其中最长的一条路径。具体解法参见代码。
问题描述:第一行给定n表示有n中长方体,2-n+1行给定长方体的长宽高。接下来开始垒高这些长方体,规定面积完全被包含的长方体可以放在上面,问最多可以垒多高。输出最高的高度。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
int n;
struct edge{
int a,b,h;
}A[100];
vector<int> Q[100];
int dp[100];
int f(int x)
{
int &a=dp[x];
if(a>0) return dp[x];
else
{
a=A[x].h; //这里是带权DAG,初始值设置为长方体高度
for(int i=0;i<Q[x].size();i++)
{
a=max(a,f(Q[x][i])+A[x].h);
}
return a;
}
}
int main()
{
while(cin>>n)
{
if(n==0) break;
for(int i=0;i<100;i++) Q[i].clear();
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
cin>>A[(i-1)*3+1].a>>A[(i-1)*3+1].b>>A[(i-1)*3+1].h;
A[(i-1)*3+2].h=A[(i-1)*3+1].a;A[(i-1)*3+2].b=A[(i-1)*3+1].b;A[(i-1)*3+2].a=A[(i-1)*3+1].h;
A[(i-1)*3+3].h=A[(i-1)*3+1].b;A[(i-1)*3+3].b=A[(i-1)*3+1].h;A[(i-1)*3+3].a=A[(i-1)*3+1].a;
}
for(int i=1;i<3*n;i++)
{
for(int j=i+1;j<=3*n;j++)
{
if(A[i].a>A[j].a&&A[i].b>A[j].b||A[i].a>A[j].b&&A[i].b>A[j].a) Q[i].push_back(j);
if(A[j].a>A[i].a&&A[j].b>A[i].b||A[j].a>A[i].b&&A[j].b>A[i].a) Q[j].push_back(i);
}
}
int ans=1;
for(int i=1;i<=3*n;i++)
{
ans=max(ans,f(i));
}
cout<<ans<<endl;
}
}