UVA - 437 The Tower of Babylon DAG上的动态规划

思路:

每个长方体都有三种放法,将每个长方体的放法都存起来,然后跑一遍如果此长方体u能够放在另一个长方体v的上面,则建一条u->v的边。然后跑一遍记忆化搜索。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int maxn=105;
int n;
int g[maxn][maxn];
struct chan
{
    int x,y,z;
}a[maxn];
int dp[maxn][maxn];
bool judge (chan a,chan b)
{
    if(a.x<b.x&&a.y<b.y) return true;
    if(a.y<b.x&&a.x<b.y) return true;
    return false;
}
int Find(int u,int v)
{
    int& ans=dp[u][v];
    if(ans!=-1) return ans;
    for (int i=1;i<=3*n;i++)
    {
        if(i==v) continue;
        if(g[v][i])
        {
            ans=max(ans,Find(v,i)+a[u].z);
        }
    }
    if(ans==-1) ans=a[u].z+a[v].z;
    return ans;
}
int main()
{
    int t=0;
    while(scanf("%d",&n)&&n)
    {
        t++;
        memset (g,0,sizeof(g));
        for (int i=1;i<=3*n;i+=3)
        {
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
            a[i+1].x=a[i].y;
            a[i+1].y=a[i].z;
            a[i+1].z=a[i].x;
            a[i+2].x=a[i].x;
            a[i+2].y=a[i].z;
            a[i+2].z=a[i].y;
        }
        for (int i=1;i<=3*n;i++)
        {
            for (int j=1;j<=3*n;j++)
            {
                if(i==j) continue;
                if(judge(a[i],a[j]))
                {
                    g[i][j]=1;
                }
            }
        }
        memset (dp,-1,sizeof(dp));
        int ans=-1;
        for (int i=1;i<=3*n;i++)
        {
            for (int j=1;j<=3*n;j++)
            {
                if(g[i][j])
                {
                    ans=max(ans,Find(i,j));
                }
            }
        }
        printf("Case %d: maximum height = %d\n",t,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41410799/article/details/88419184
今日推荐