UVA 437 The Tower of Babylon | dp

来源:互联网 发布:数据与R pdf 编辑:程序博客网 时间:2024/04/30 00:02

题意:

你有n个方体,每个方体你有无限个。求出你所能堆叠方体最高的高度。要求下面的方体长宽均要比其上面的方体的长宽大(相等不行);


思路:

先把一个方体上面所能放的方体连一条线。就成了DAG(有向无环图)的不定起点最长路问题。一个方体因为长宽高不一定相同,因此要把所给的方体看成3*n个方体,每个方体无限个。


状态定义:

dp[i]:从第i个方块出发所获得的最大高度。

状态转移:

dp[i] = max(dp[i], d(next) + next.h); //我采用的是递归的形式,d(next)表示从第i块的上面那块的最大高度 + next本身的高度next.h;


AC代码:

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <vector>using namespace std;const int MAXN = 95;int n;struct Point{    int x, y;    int h;    vector <int> l;}a[MAXN];int dp[MAXN];int d(int x){    if(dp[x] > 0)   return dp[x];    dp[x] = a[x].h;    for(int i = 0;i < a[x].l.size(); i++)    {        int next = a[x].l[i];        dp[x] = max(dp[x], d(next) + a[x].h);    }    return dp[x];}int solve(){    memset(dp, 0, sizeof(dp));    for(int i = 1;i <= 3*n; i++)    {       dp[i] = d(i);    }    int res = -1;    for(int i = 1;i <= 3*n; i++)    {        res = max(res, dp[i]);    }    return res;}int main(){    int cas = 0;    while(scanf("%d",&n), n)    {        int x, y ,z;        for(int i = 1,j = 1;i <= n; i++)        {            scanf("%d%d%d", &x, &y, &z);            a[j++] = (Point){x, y, z};            a[j++] = (Point){x, z, y};            a[j++] = (Point){y, z, x};        }        //build the graph        for(int i = 1;i <= 3*n; i++)        {            Point &e = a[i];            e.l.clear();            for(int j = 1;j <= 3*n; j++)            {                if(i == j)  continue;                Point &t = a[j];                if((t.x < e.x && t.y < e.y ) || (t.y < e.x && t.x < e.y))                    e.l.push_back(j);            }        }        printf("Case %d: maximum height = %d\n", ++cas, solve());    }    return 0;}


0 0
原创粉丝点击