uva 437 The Tower of Babylon 巴比伦塔

题目大意:
给你一堆方块的长宽高,让你垒出个巴比伦塔,这个塔越高越好。要求是每个方块下面的方块的长度a要大于上面的长度a,宽度b要大于上面的宽度b。(杭电上那道山寨的猴子吃香蕉的那个和此题是原题)
比如样例1里面的 10 20 30 可以这样
第二层:10 20 30
第一层:30 20 10
+______
相加 = 40
思路见代码下方:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
#include <iomanip>
using namespace std;
struct cube
{
    int a,b,c;
};
cube cu[91];
int dp[91];
bool cmp(const cube &a,const cube &b)
{
    return a.a*a.b>b.a*b.b;
}
int max(int a,int b)
{
    if(a>b)
    return a;
    return b;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,a,b,c,ans,k=1;
    while(cin>>n,n)
    {
        memset(dp,0,sizeof(dp));
        ans=0;
        for(int i=1;i<=n*3;)
        {
            cin>>a>>b>>c;
            cu[i].a=a,cu[i].b=b,cu[i].c=c;
            i++;
            cu[i].a=c,cu[i].b=b,cu[i].c=a;
            i++;
            cu[i].a=a,cu[i].b=c,cu[i].c=b;
            i++;
        }
        sort(cu+1,cu+1+3*n,cmp);
        for(int i=1;i<=3*n;i++)
        {
            int tem=0;
            for(int j=1;j<i;j++)
            {
                if((cu[j].a>cu[i].a&&cu[j].b>cu[i].b)||(cu[j].a>cu[i].b&&cu[j].b>cu[i].a))
                tem=max(tem,dp[j]);
            }
            dp[i]=tem+cu[i].c;
            ans=max(ans,dp[i]);
        }
        cout<<"Case "<<k++<<": maximum height = "<<ans<<endl;
    }
    return 0;
}










思路:
正常方法解不出来,一般就是动态规划问题啦~考虑第dp[i]代表第i个方块为最顶端方块所能垒到的最大高度,则有dp[i]=max(dp[j])+cu[i].c (j小于i)。按照这个思路写完,你会发你答案明显不对滴。联想一下最长递增序列问题,最长递增序列问题是在给定的数列顺序下求解。所以此题也要有考虑顺序问题,每次找到第i个方块的时候要保证dp[i]一定能索引到i之前的最大值,以便能求出在以i为最顶端方块时的最大值(不信自己用第一样例试试)。所以可以用按a*b的面积排序的想法,当然应该也可以用a的长度和b的长度进行双重判断的方法,排序后应用上面的转移方程就行了~

你可能感兴趣的:(uva 437 The Tower of Babylon 巴比伦塔)