SCAU专题训练II - DP---E--The Tower of Babylon

简单说下

这道题目的话,用到了LIS,就是LIS的变形。本题的关键就是如何将一个三维的题目化成一维(也就是三组数据化成一组符合LIS的数据来解)。题目的意思是叫我们求出这些砖头能堆放的最大高度,堆放时有限制条件,就是上面的砖头的长和宽一定要小于下面的,那么这道题目我们如何建模呢??我们知道3个数的组合有6种(其实这道题目,根据对称,真正的数据只需要三组,但是因为我是按六组来写的,所以就按六组来说),我们将这六组数据都存入结构体数组中(有对应的x,y,z),以下每次输入数据都这样做。然后对这些数据进行排序,我们知道,如果一个长方形它的面积小于另一个长方形,那么它的两条边至少有一条边是小于的,所以我们就用这个来当sort的判断条件。此时我们得到了一个面积从小到大或从大到小排列的结构体数组,然后我们只需要找到高h的最长上升子序列即可,答案就是最长上升子序列的路径和相加。

代码如下

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
typedef struct
{
    int x,y,z;
} ZT;
bool cmp(ZT X,ZT Y)
{
    return X.x*X.y>Y.x*Y.y;
}
int dp[1000]= {0};
int main()
{
    int case1=0,n;
    while(cin>>n&&n!=0)
    {
        case1++;
        ZT a[200];
        int j=1;
        for(int i=1; i<=n; i++)
        {
            cin>>a[j].x>>a[j].y>>a[j].z;
            a[j+1].x=a[j].y,a[j+1].y=a[j].x,a[j+1].z=a[j].z;
            a[j+2].x=a[j].x,a[j+2].y=a[j].z,a[j+2].z=a[j].y;
            a[j+3].x=a[j].z,a[j+3].y=a[j].y,a[j+3].z=a[j].x,
            a[j+4].x=a[j].y,a[j+4].y=a[j].z,a[j+4].z=a[j].x,
            a[j+5].x=a[j].z,a[j+5].y=a[j].x,a[j+5].z=a[j].y;
            j=j+6;
        }
        sort(a+1,a+j,cmp);
        int maxlen=0;
        for(int i=1;i<j;i++)
        {
            dp[i]=a[i].z;
            for(int k=1;k<i;k++)
            {
                if(a[i].x<a[k].x&&a[i].y<a[k].y)
                {
                    dp[i]=max(dp[i],dp[k]+a[i].z);
                }
            }
           if(dp[i]>maxlen)
                maxlen=dp[i];
        }
        printf("Case %d: maximum height = %d\n",case1,maxlen);
    }
    return 0;
}
发布了43 篇原创文章 · 获赞 26 · 访问量 3088

猜你喜欢

转载自blog.csdn.net/Leo_zehualuo/article/details/104434608