DP 动态规划 Problem E 1005 最大递增子序列

来源:互联网 发布:17%退税率出口退税算法 编辑:程序博客网 时间:2024/05/29 09:31

Problem E  ID:1005


简单题意:提供无限个若干种长为xi,宽为yi,高为zi的砖块,砖块可以调整方向(如长也可以为宽或高)。若一个砖块的长和宽分别比另一个砖块的长和宽小,则此砖块可以垒在后一个砖块的上面。问:最大可以垒多高?


解题思路形成过程:实际上是一种条件稍复杂些的最大递增子序列问题。

            每种砖块的高共有三种情况(*3),其中每种情况分别对应两种长和宽(*2),所以每个砖块共有6种摆放方式,n个砖块有6*n种摆放方式。

            每输入一种砖块类型,将对应的6种长、宽、高储存到相应的数组中。

            按照砖块长的大小由小到大进行排序,如果两个砖块的长相同,则按照砖块宽的大小由小到大进行排序。

            从第一个砖块开始按照求最大递增子序列问题的DP方式进行遍历,遍历至最后一个砖块,即可求得最大值。


感想:看似比最基本的最大递增子段和问题要复杂很多,但耐下心来就会发现,只是多了对数组进行存储和排序操作,DP的部分多一些思考罢了。重要的是要看出问题需要用什么方式来进行解决,如何抽象化。


代码:
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int n;int x[181],y[181],z[181];int dp[181];void exch_1(int i){    x[i+1]=x[i];    y[i+1]=z[i];    z[i+1]=y[i];}void exch_2(int i){    x[i+2]=y[i];    y[i+2]=x[i];    z[i+2]=z[i];    x[i+3]=y[i];    y[i+3]=z[i];    z[i+3]=x[i];}void exch_3(int i){    x[i+4]=z[i];    y[i+4]=x[i];    z[i+4]=y[i];    x[i+5]=z[i];    y[i+5]=y[i];    z[i+5]=x[i];}void cmp(){    for(int i=1;i<6*n;++i)        for(int j=0;j<i;++j)        {            if(x[j]>x[i])            {                int t=x[i];                x[i]=x[j];                x[j]=t;                t=y[i];                y[i]=y[j];                y[j]=t;                t=z[i];                z[i]=z[j];                z[j]=t;            }            else if(x[j]==x[i])                if(y[j]>y[i])                {                    int t=y[i];                    y[i]=y[j];                    y[j]=t;                    t=z[i];                    z[i]=z[j];                    z[j]=t;                }        }}int DP(){    int cmax=z[0];    dp[0]=z[0];    for(int i=1;i<6*n;++i){        dp[i]=z[i];        for(int j=0;j<i;++j)        {            if(x[j]<x[i]&&y[j]<y[i])                if(dp[j]+z[i]>dp[i]){                    dp[i]=dp[j]+z[i];                }        }        if(dp[i]>cmax)            cmax=dp[i];    }    return cmax;}int main(){    freopen("1.txt","r",stdin);    int m=1;    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=0;i<6*n;i+=6){            scanf("%d %d %d",&x[i],&y[i],&z[i]);            exch_1(i);            exch_2(i);            exch_3(i);        }        cmp();        int t=DP();        printf("Case %d: maximum height = %d\n",m++,t);    }}


0 0
原创粉丝点击