[DP] HDU 1069

来源:互联网 发布:C语言手写笔记图片 编辑:程序博客网 时间:2024/06/05 17:26

题意

给定箱子种类数量n,及对应长宽高,每个箱子数量无限,求其能叠起来的最大高度是多少(上面箱子的长宽严格小于下面箱子)

思路

每种箱子有三种放置方式且数量无限,故可将每个箱子按三个箱子看待。对所有箱子按主长副宽进行先大后小排序,那么问题就成了求最大递增子串。
因为n的范围特别小,只有30,所以直接两重循环dp即可

以上是dalao的做法
我自己写的是放了六个…..似乎也有人这么做
然后按照长排序,在求宽关于高的最长递增子序列

代码

#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>#include <vector>#define N 200#define INF 0x7f7f7f7fusing namespace std;struct Node {    int x, y, z;    bool operator< ( const Node t ) const { return ( x > t.x ); }};vector<Node> v;int dp[ N ];int LIS ( int n ) {    int mx = 0;    for ( int i = 0; i < n; ++i ) {        dp[ i ] = v[ i ].z;        for ( int j = 0; j < i; ++j ) {            if ( v[ j ].x > v[ i ].x && v[ j ].y > v[ i ].y && dp[ j ] + v[ i ].z > dp[ i ] )                dp[ i ] = dp[ j ] + v[ i ].z;            if ( dp[ i ] > mx )                mx = dp[ i ];        }    }    return mx;}int main () {    int n, kse = 0;    while ( ~scanf ( "%d", &n ) && n ) {        v.clear ();        memset ( dp, 0, sizeof ( dp ) );        for ( int i = 0; i < n; ++i ) {            int a, b, c;            scanf ( "%d%d%d", &a, &b, &c );            v.push_back ( Node{a, b, c} );            v.push_back ( Node{a, c, b} );            v.push_back ( Node{b, a, c} );            v.push_back ( Node{b, c, a} );            v.push_back ( Node{c, a, b} );            v.push_back ( Node{c, b, a} );        }        sort ( v.begin (), v.end () );        int sol = LIS ( n * 6 );        printf ( "Case %d: maximum height = %d\n", ++kse, sol );    }    return 0;}