ecnu 1244 积木游戏(黑书)DP

来源:互联网 发布:前瞻网数据库可靠吗 编辑:程序博客网 时间:2024/05/20 08:43

dp[num][pos][pre][statu] 表示之前已经有num个堆,现在考虑第pos个长方体,且之前堆的最上面的长方体的下标为pre(用statu表示那一面朝上)之后还能获得的最大高度

对与目前的pos长方体,1.可以单独成堆,

                                         2.可以加入之前的堆(放在pre上面)

                                         3.或者直接丢掉

 这样就能向后转移了,我用的记忆话搜索来做的,这样比较简单,实在是不敢想象递推有多麻烦

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;#define MAX 0x3f3f3f3fstruct Rectangle{    int a, b, c;};int dp[110][110][110][3];int N, M;Rectangle r[110];int geta( int pos, int statu ){    int a = r[pos].a;    int b = r[pos].b;    int c = r[pos].c;    if( statu == 0 ){        return a > b ? a : b;    }else if( statu == 1 ){        return a > c ? a : c;    }else{        return b > c ? b : c;    }}int getb( int pos, int statu ){    int a = r[pos].a;    int b = r[pos].b;    int c = r[pos].c;    if( statu == 0 ){        return a > b ? b : a;    }else if( statu == 1 ){        return a > c ? c : a;    }else{        return b > c ? c : b;    }}int DFS( int num, int pos, int pre, int statu ){    if( pos > N ){        return 0;    }    if( dp[num][pos][pre][statu] != -1 ){        return dp[num][pos][pre][statu];    }    int ans = 0;    //丢弃该长方体    ans = max( ans, DFS( num, pos + 1, pre, statu ) );    //该长方体独立成堆    if( num < M ){        ans = max( ans, r[pos].c + DFS( num + 1, pos + 1, pos, 0 ) );//c为高        ans = max( ans, r[pos].b + DFS( num + 1, pos + 1, pos, 1 ) );//b为高        ans = max( ans, r[pos].a + DFS( num + 1, pos + 1, pos, 2 ) );//a为高    }    //该长方体加入之前的堆    int prea = geta( pre, statu );    int preb = getb( pre, statu );    int posa, posb;    posa = geta( pos, 0 );    posb = getb( pos, 0 );    if( posa <= prea && posb <= preb ){//c为高        ans = max( ans, r[pos].c + DFS( num, pos + 1, pos, 0 ) );    }    posa = geta( pos, 1 );    posb = getb( pos, 1 );    if( posa <= prea && posb <= preb ){//b为高        ans = max( ans, r[pos].b + DFS( num, pos + 1, pos, 1 ) );    }    posa = geta( pos, 2 );    posb = getb( pos, 2 );    if( posa <= prea && posb <= preb ){//a为高        ans = max( ans, r[pos].a + DFS( num, pos + 1, pos, 2 ) );    }    return dp[num][pos][pre][statu] = ans;}int main(){    while( scanf( "%d%d", &N, &M ) != EOF ){        r[0].a = r[0].b = r[0].c = MAX;        for( int i = 1; i <= N; i++ ){            cin >> r[i].a >> r[i].b >> r[i].c;        }        memset( dp, -1, sizeof( dp ) );        cout << DFS( 1, 1, 0, 0 ) << endl;    }    return 0;}


0 0
原创粉丝点击