hdu1069(dp)

来源:互联网 发布:大数据开发云盘 编辑:程序博客网 时间:2024/06/08 05:31

hdu1069 http://acm.hdu.edu.cn/showproblem.php?pid=1069
题意:
一群研究人员设计了一个检测猴子IQ的实验。他们将一个香蕉放在了房子的屋顶,同时,给小猴子一些木块。如果猴子足够聪明,他将可以用一个木块叠加另一个木块来构建一个木塔来够到香蕉。
研究人员有N种木块,无限制提供各种木块。第i个木块是一个长方体,坐标是(xi,yi,zi)。木块摆放可以调整方向,任意两条边可以当做长方体的底边,那么另一边是高。
他们想知道最高可以搭建多少来够到房顶。问题是:在构建木塔时,一个木块要完全覆盖上面一个木块,只要上面的木块的底座两边要都小于下面木块底座的两边(我写的代码中只需上面木块的最长底边小于下面木块的最长边,另一条上面的小于下面的就可以了),因为小猴子需要可以踩的地方。这意思是,例如,木块有同样长度的底边,就不能叠。
数据:N种木块,每种木块的x, y, z;

每种木块可以无数次取,但仔细想想其实每种木块最多拿2块,比如说6 8 10,有三种情况,第一种底边6 8,高10,第二种底边6 10,高8,第三种底边8 10,高6。但据题意,第一种可以和第三种一起拿,而第二种只能单独拿,因此最多拿两块,而且不能重复。其实dp的一种题目,可以将三种都存入,然后就变成了01背包问题啦!之后就是我们熟悉的回溯过程了还有我的point数组x要大于等于y,这样在比较是否可以搭在j上时,只需判断(point[i].x < point[j].x && point[i].y < point[j].y)就好了^^这道题不算难,是一种经典题型,我RE了两发,等我将dp数组从二维改为一维就AC了,为什么现在也不知道==
#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>using namespace std;struct  Node{    int x, y;    int high;}point[1100];int dp[1100];int comp(struct Node a, struct Node b){    if(a.x == b.x)    {        if(a.y == b.y)        {            a.high > b.high;        }        return a.y > b.y;    }    return a.x > b.x;}int main(){    int n, m;    int i, j, k, mmax, Max;    int x, y, z;    m = 0;    while(~scanf("%d", &n) && n)    {        k = 0;   m++;        memset(point, 0, sizeof(point));        for(i = 0; i < n; i++)        {            scanf("%d%d%d", &x, &y, &z);            if(x == y && y == z)            {                point[k].x = point[k].y = point[k].high = x;                k++;            }            else            {                for(j = 0; j < 3; j++)                {                    if(j == 0)                    {                        point[k].x = max(x, y);                        point[k].y = min(x, y);                        point[k].high = z;                        k++;                    }                    if(j == 1)                    {                        point[k].x = max(y, z);                        point[k].y = min(y, z);                        point[k].high = x;                         k++;                    }                    if(j == 2)                    {                        point[k].x = max(z, x);                        point[k].y = min(z, x);                        point[k].high = y;                        k++;                    }                }            }        }        sort(point, point+k, comp);        Max = point[0].high;        for(i = 0; i < k; i++)        {            dp[i] = point[i].high;            mmax = point[i].high;            for(j = 0; j < i; j++)            {                z = point[i].high;                if(point[i].x < point[j].x && point[i].y < point[j].y)                {                    z += dp[j];                }                mmax = max(z, mmax);            }            dp[i] = mmax;            Max = max(Max, mmax);        }        cout << "Case " << m << ": maximum height = " << Max << endl;    }    return 0;}

请多指教^^

0 0
原创粉丝点击