您的位置:首页 > 其它

ecnu 1244 积木游戏(黑书)DP

2014-03-03 21:12 323 查看
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 0x3f3f3f3f

struct 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: