DAG 动态规划 巴比伦塔 B - The Tower of Babylon

题目:The Tower of Babylon

这是一个DAG 模型,有两种常规解法

1.记忆化搜索, 写函数,去查找上一个符合的值,不断递归

2.递推法

 

方法一:记忆化搜索
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
    int x,y,z;
    node(int x=0,int y=0,int z=0) : x(x) , y(y) , z(z){}
}exa[5000];

bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y>b.y;
    else return a.x>b.x;
}

int n;
int dp[10000];
bool vis[10000];

int d(int e)
{
    if(vis[e]) return dp[e];
    vis[e]=1;
    int &ans=dp[e];
    ans=exa[e].z;
    for(int i=1;i<e;i++)
    {
//        printf("exa[%d].x=%d\n",i,exa[i].x);
//        printf("exa[%d].y=%d\n",i,exa[i].y);
//        printf("exa[%d].x=%d\n",e,exa[e].x);
//        printf("exa[%d].y=%d\n",e,exa[e].y);
        if(exa[i].x>exa[e].x&&exa[i].y>exa[e].y)
        {
            ans=max(ans,d(i)+exa[e].z);
          //  cout<<ans<<" "<<i<<endl;
        }
    }
    return ans;
}

int main()
{
    int num=0;
    while(scanf("%d",&n)==1&&n)
    {
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            exa[i]=node(a,b,c);
            exa[n+i]=node(b,c,a);
            exa[n*2+i]=node(b,a,c);
            exa[n*3+i]=node(a,c,b);
            exa[n*4+i]=node(c,a,b);
            exa[n*5+i]=node(c,b,a);
        }
        n*=6;
        sort(exa+1,exa+n+1,cmp);
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            int tmp=d(i);
            ans=max(ans,tmp);
        }
        printf("Case %d: maximum height = %d\n",++num,ans);
    }
    return 0;
}

  

方法二:递推法
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
    int x,y,z;
    node(int x=0,int y=0,int z=0) : x(x) , y(y) , z(z){}
}exa[500];
bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y>b.y;
    else return a.x>b.x;
}

int n;
int dp[1000];

int main()
{
    int num=0;
    while(scanf("%d",&n)==1&&n)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            exa[i]=node(a,b,c);
            exa[n+i]=node(b,c,a);
            exa[n*2+i]=node(b,a,c);
            exa[n*3+i]=node(a,c,b);
            exa[n*4+i]=node(c,a,b);
            exa[n*5+i]=node(c,b,a);
        }
        n*=6;
        int ans=0;
        sort(exa+1,exa+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            dp[i]=exa[i].z;
            for(int j=1;j<i;j++)
            {
                if(exa[i].x<exa[j].x&&exa[i].y<exa[j].y)
                {
                    dp[i]=max(dp[i],dp[j]+exa[i].z);
                    //cout<<dp[i]<<"ww "<<i<<endl;
                }//cout<<dp[i]<<" "<<i<<endl;
            }
            ans=max(ans,dp[i]);
        }
        printf("Case %d: maximum height = ",++num);
        cout<<ans<<endl;
    }
    return 0;
}

 

posted @ 2019-01-07 15:36  EchoZQN  阅读(195)  评论(0编辑  收藏  举报