zoukankan      html  css  js  c++  java
  • 动态规划2-----hdu1069

    首先这道题目先要理解题目的意思。

    用一些方块堆塔,给出的每种方块个数是无限的,只有满足长宽都小于下面一个方块的方块才能摆上去。

    首先这道题需要一个转化。

    每个方块有3个不同的面,每个面长宽交换,一共每个方块最多有6种情况。

    X Y Z

    1 2 3

    2 1 3

    3 1 2

    1 3 2

    2 3 1

    3 2 1

    如果长宽高有相同的部分还可以减少一些情况

    然后对面积,长,宽,从小到大排序。

    这步做完dp的准备才算完成。

    下面分析dp部分。

    如果不用dp,用贪心先试试,先把最大的面积放在下面,然后循环面积比他小的,如果满足长宽都小就摆上去,循环一遍摆完为止。

    for(n->1)

    {

            for(n-1->1)

            {

                  max +=z;

            }

    }

    看上去貌似是可以的,但是其实是不行的,因为你摆了n-1之后,能不能摆n-3了,如果不能,你就不知道n-3和n-4的组合是不是比摆n-1要好了,所以贪心失败。

    dp试试

    从小到大,先摆最小的,然后用下一个,循环比所有他小的(之前已经摆好了),其中dp【】数据最优的,保存在当前dp【】数组中并且加上当前的方块高度。

    状态转移方程

    dp【now】 = max(for(now->1)循环中dp【】值最大的) + bolck【now】;

    初始值

    全部为0

    下面给出dp的代码和贪心的代码

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    /*dp,hdu1069*/
    
    int dp[500];//动态规划的数组
    
    struct block
    {
        int x;//
        int y;//
        int z;//
        int s;//面积
    };
    
    int cmp(const void * a, const void * b)
    {
        struct block * p2 = (struct block *)a;
        struct block * p1 = (struct block *)b;
        
        if(p1->s != p2->s) 
            return p2->s - p1->s;
        else if(p1->x != p2->x)
            return p2->x - p1->x;
        else 
            return p2->y - p1->y;
    }
    
    int    main()
    {
        int n;//方块个数
        int i,j;//循环变量
        int number=0;//记录可行方块数,一个方块最多有6钟可行方案
        int maxNumber=0;//记录结果
        int reslut=1;//记录次数
        int x,y,z;//用户输入
        int tempMax,tempX,tempY;//临时变量
    
        struct block blocks[500];//保存所有情况方块
        while (true)
        {
            cin>>n;
            if(n==0)
                break;
    
            number=0;
            for (i = 0; i < n; i++)
            {
                cin>>x>>y>>z;
    
                //记录6钟情况
                if(x==y&&y==z)
                {
                    blocks[number].x = x;
                    blocks[number].y = y;
                    blocks[number].z = z;
                    blocks[number].s = x*y;
                    number++;
                }
                else
                {
                    if(x==y)
                    {
                        blocks[number].x = x;
                        blocks[number].y = y;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = x;
                        blocks[number].y = y;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
    
                        blocks[number].x = y;
                        blocks[number].y = x;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
                    }
                
    
                    if(x==z)
                    {
                        blocks[number].x = x;
                        blocks[number].y = z;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = x;
                        blocks[number].y = z;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
    
                        blocks[number].x = z;
                        blocks[number].y = x;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
                    }
    
                
                    if(y==z)
                    {
                        blocks[number].x = z;
                        blocks[number].y = y;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = z;
                        blocks[number].y = y;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
    
                        blocks[number].x = y;
                        blocks[number].y = z;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
                    }
                }
            }
    
            //对于s-x-y小到大排序所有方块
            qsort(blocks, number, sizeof(block), cmp);
    
            maxNumber = 0;
            tempMax=0;
            dp[0] = blocks[0].z;
            maxNumber = dp[0];
            for (i = 1; i < number; i++)
            {
                dp[i]=blocks[i].z;
                tempMax=0;
                tempX=blocks[i].x;
                tempY=blocks[i].y;
    
    
                for (j = i-1; j >= 0; j--)
                {
                    if(tempX > blocks[j].x && tempY > blocks[j].y)
                    {
                        if(tempMax < dp[j])
                            tempMax=dp[j];
                    }
                }
    
                dp[i] += tempMax;
                if(dp[i] > maxNumber)
                    maxNumber=dp[i];
            }
    
            printf("Case %d: maximum height = %d
    ",reslut,maxNumber);
            reslut++;
        }
        return 0;
    }

    贪心

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    /*贪心,失败,hdu1069*/
    
    struct block
    {
        int x;//
        int y;//
        int z;//
        int s;//面积
    };
    
    int cmp(const void * a, const void * b)
    {
        struct block * p1 = (struct block *)a;
        struct block * p2 = (struct block *)b;
        
        if(p1->s != p2->s) 
            return p2->s - p1->s;
        else if(p1->x != p2->x)
            return p2->x - p1->x;
        else 
            return p2->y - p1->y;
    }
    
    int    main()
    {
        int n;//方块个数
        int i,j;//循环变量
        int number=0;//记录可行方块数,一个方块最多有6钟可行方案
        int maxNumber=0;//记录结果
        int reslut=1;//记录次数
        int x,y,z;//用户输入
        int tempMax,tempX,tempY;
    
        struct block blocks[500];
        while (true)
        {
            cin>>n;
            if(n==0)
                break;
    
            number=0;
            for (i = 0; i < n; i++)
            {
                cin>>x>>y>>z;
    
                //记录6钟情况
                if(x==y&&y==z)
                {
                    blocks[number].x = x;
                    blocks[number].y = y;
                    blocks[number].z = z;
                    blocks[number].s = x*y;
                    number++;
                }
                else
                {
                    if(x==y)
                    {
                        blocks[number].x = x;
                        blocks[number].y = y;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = x;
                        blocks[number].y = y;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
    
                        blocks[number].x = y;
                        blocks[number].y = x;
                        blocks[number].z = z;
                        blocks[number].s = x*y;
                        number++;
                    }
                
    
                    if(x==z)
                    {
                        blocks[number].x = x;
                        blocks[number].y = z;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = x;
                        blocks[number].y = z;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
    
                        blocks[number].x = z;
                        blocks[number].y = x;
                        blocks[number].z = y;
                        blocks[number].s = x*z;
                        number++;
                    }
    
                
                    if(y==z)
                    {
                        blocks[number].x = z;
                        blocks[number].y = y;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
                    }
                    else
                    {
                        blocks[number].x = z;
                        blocks[number].y = y;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
    
                        blocks[number].x = y;
                        blocks[number].y = z;
                        blocks[number].z = x;
                        blocks[number].s = y*z;
                        number++;
                    }
                }
            }
    
            qsort(blocks, number, sizeof(block), cmp);
    
            maxNumber = 0;
            tempMax=0;
            tempX=0;
            tempY=0;
            for (i = 0; i < number; i++)
            {
                tempMax=blocks[i].z;
                tempX=blocks[i].x;
                tempY=blocks[i].y;
                for (j = i+1; j < number; j++)
                {
                    if(tempX > blocks[j].x && tempY > blocks[j].y)
                    {
                        tempX=blocks[j].x;
                        tempY=blocks[j].y;
                        tempMax += blocks[j].z;
                    }
                }
                if(tempMax > maxNumber)
                    maxNumber=tempMax;
            }
    
            printf("Case %d: maximum height = %d
    ",reslut,maxNumber);
            reslut++;
        }
        return 0;
    }

    经过实践,贪心可以满足前几组数据,但是最后一组数据就GG了

    而且贪心和dp的效率在这里均为O(NlogN + N!)所以并没有快。

    再一次证明dp确实很多时候比贪心好用。

    但是其实最重要的是在dp之前对题目的分析,要把一个题目抽象到一组数,这个才是需要特别去考虑的事情,如果之前都想不到的话是肯定得不到最后的答案的。

  • 相关阅读:
    SQL语言的组成
    存储过程中使用事务
    sql语法:inner join on, left join on, right join on详细使用方法
    Sql Server服务 远程过程调用失败
    UML学习之初步总结
    UML学习之用例图
    使用redis
    msserver的update or insert语句
    c#操作注册表的意外
    托管代码编写mssql存储过程
  • 原文地址:https://www.cnblogs.com/linkstar/p/5373228.html
Copyright © 2011-2022 走看看