POJ 2241 The Tower of Babylon

额。这是一道DAG上的dp题。

题目给出了n种方块,这n种方块都可以翻转,于是总共就有3n种方块,于是可以把问题转化成LIS来处理。我这里偷懒照着白书写了个记忆化搜索。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct T
{
    int x;
    int y;
    int h;
};
T m[100],ck[2000000];
int map[100][100],d[100],lm;
int dp(int n)
{
    int i,j;
    if (d[n] != m[n].h)
        return d[n];
    for (i=0; i<lm; i++)
    {
        if (map[n][i] != 0)
        {
            j=dp(i)+map[n][i];
            d[n]=d[n]>j?d[n]:j;
        }
    }
    return d[n];
}
int main()
{
    int n,i,j,t1,t2,t3,ans,prob;
    prob=1;
    while (1)
    {
        lm=0;
        scanf("%d",&n);
        if (n == 0)
            break;
        while (n--)
        {
            scanf("%d%d%d",&t1,&t2,&t3);
            m[lm].x=t1>t2?t2:t1;
            m[lm].y=t1>t2?t1:t2;
            m[lm].h=t3;
            lm++;
            m[lm].x=t3>t2?t2:t3;
            m[lm].y=t3>t2?t3:t2;
            m[lm].h=t1;
            lm++;
            m[lm].x=t1>t3?t3:t1;
            m[lm].y=t1>t3?t1:t3;
            m[lm].h=t2;
            lm++;
        }
        memset(map,0,sizeof(map));
        for (i=0; i<lm; i++)
        {
            d[i]=m[i].h;
            for (j=0; j<lm; j++)
            {
                if (m[i].x > m[j].x && m[i].y > m[j].y)
                    map[i][j]=m[i].h;
            }
        }
        ans=-1;
        for (i=0; i<lm; i++)
        {
            j=dp(i);
            if (j>ans)
                ans=j;
        }
        printf("Case %d: maximum height = %d\n",prob,ans);
       /* for (i=0; i<lm; i++)
        {
            printf("%d %d %d\n",m[i].x,m[i].y,m[i].h);
        }
        for (i=0; i<lm; i++)
        {
            for (j=0; j<lm; j++)
            {
                printf("%d ",map[i][j]);
            }
            printf("\n");
        }*/
        prob++;
    }
}


你可能感兴趣的:(POJ 2241 The Tower of Babylon)