uva437The Tower of Babylon(不一样的dp)

来源:互联网 发布:linux-mint 搜狗输入法 编辑:程序博客网 时间:2024/06/14 05:55

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

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

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

代码(有点长)

#include <cstdio>#include <cstring>#include <algorithm>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;}

0 0
原创粉丝点击