uva437The Tower of Babylon(不一样的dp)


我的思路和刘汝佳老师的思路不一样:

思路: 把一个立方体变成6个立方体 ,即长宽高都不一样。

定义状态: d[i] 为以下标为i的木块为起点所能摞的最高的高度,记忆化搜索就可以了。

代码(有点长)

#include 
#include 
#include 

using namespace std;

struct node
{
    int a,b,c;
}blocks[100];
int cnt,n ;
int per[5];
int v_p[5];
int per_p[5];
int g[200][200];
int d[200];
int kase = 1;
void dfs(int step)

{
    if(step == 3)
    {
        blocks[cnt].a = per[0];
        blocks[cnt].b = per[1];
        blocks[cnt].c = per[2];
        cnt++;
        return ;
    }
    for(int i = 0; i < 3; ++i)
    {
        if(!v_p[i])
        {
            per[step] = per_p[i];
            v_p[i] = 1;
            dfs(step + 1);
            v_p[i] = 0;
        }
    }
}
int dp(int i)

{
    int& ans = d[i];
    if(ans > 0) return ans;
    ans = blocks[i].c ;
    for(int j = 0;j < 6 * n;++j)
        if(g[i][j])
             ans = max(ans,dp(j) + blocks[i].c);
    return ans;
}
int main()

{
    while(~scanf("%d",&n) && n)
    {
        memset(g,0,sizeof(g));
        memset(blocks,0,sizeof(blocks));
        memset(d,0,sizeof(d));
        cnt = 0;
        for(int i = 0; i < n; ++i)
        {
            memset(v_p,0,sizeof(v_p));
            scanf("%d%d%d",&per_p[0],&per_p[1],&per_p[2]);
            dfs(0);
        }
        for(int i = 0; i < 6 * n; ++i)
        {
            for(int j = 0; j < 6 * n; ++j)
            {
                if(i != j)
                {
                    if((blocks[i].a > blocks[j].a && blocks[i].b > blocks[j].b) || (blocks[i].a > blocks[j].b && blocks[i].b > blocks[j].a))
                          g[i][j] = 1;
                    else if((blocks[i].a < blocks[j].a && blocks[i].b < blocks[j].b) || (blocks[i].a > blocks[j].b && blocks[i].b > blocks[j].a))
                        g[j][i] = 1;
                }
            }
        }
        /*for(int i = 0;i < 6 * n;++i)
            printf("%d %d %d\n",blocks[i].a,blocks[i].b,blocks[i].c);
        for(int i = 0;i < 6 * n;++i)
        {
            for(int j = 0;j < 6 * n;++j)
                printf("%d ",g[i][j]);
            printf("\n");
        }*/
        int ans;
        for(int i = 0;i < 6 * n;++i)
            ans = dp(i);
        for(int i = 0;i < 6 * n;++i)
            if(ans < d[i])
                ans = d[i];
        printf("Case %d: maximum height = %d\n",kase++,ans);
    }
    return 0;
}

你可能感兴趣的:(DP)