ecnu1244 积木游戏
找有这个题目的oj找的好辛苦
算法详见黑书119页
动态规划
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> using namespace std; struct toy { int x; int y; int z; }p[110]; //1代表x和y在上 //2代表x和z在上 //3代表y和z在上 int d[110][110][110][4]; int n,m; //编号为1,2,,,,n //d[i][a][b][k]表示已经堆出了i个堆,已经考虑了a个木块,顶上木块编号为b,且k面朝上之后还能获得的最大高度 void init() { int i,j,k,l; for(i=0;i<=m+1;i++) { for(j=0;j<=n+1;j++) { for(k=0;k<=n+1;k++) { for(l=0;l<=5;l++) { d[i][j][k][l]=-1; } } } } } //编号为1,2,,,,n //d[i][a][b][k]表示已经堆出了i个堆,已经考虑了a个木块,顶上木块编号为b,且k面朝上之后还能获得的最大高度 bool check(toy a,int k,int x,int y) { int m,n; if(k==1) { m=a.x; n=a.y; } if(k==2) { m=a.x; n=a.z; } if(k==3) { m=a.y; n=a.z; } if((x<=m&&y<=n)||(x<=n&&y<=m)) { return true; } return false; } void found(int i,int a,int b,int k) { //处理编号a+1的木块 //新起一堆的处理 if(a==n) { d[i][a][b][k]=0; return; } if(i<m) { if(d[i+1][a+1][a+1][1]==-1) { found(i+1,a+1,a+1,1); } if(d[i][a][b][k]<d[i+1][a+1][a+1][1]+p[a+1].z) { d[i][a][b][k]=d[i+1][a+1][a+1][1]+p[a+1].z; } if(d[i+1][a+1][a+1][2]==-1) { found(i+1,a+1,a+1,2); } if(d[i][a][b][k]<d[i+1][a+1][a+1][2]+p[a+1].y) { d[i][a][b][k]=d[i+1][a+1][a+1][2]+p[a+1].y; } if(d[i+1][a+1][a+1][3]==-1) { found(i+1,a+1,a+1,3); } if(d[i][a][b][k]<d[i+1][a+1][a+1][3]+p[a+1].x) { d[i][a][b][k]=d[i+1][a+1][a+1][3]+p[a+1].x; } } //加在当前堆 if(check(p[b],k,p[a+1].x,p[a+1].y)) { if(d[i][a+1][a+1][1]==-1)//check判断是否合法 { found(i,a+1,a+1,1); } if(d[i][a][b][k]<d[i][a+1][a+1][1]+p[a+1].z) { d[i][a][b][k]=d[i][a+1][a+1][1]+p[a+1].z; } } if(check(p[b],k,p[a+1].x,p[a+1].z)) { if(d[i][a+1][a+1][2]==-1) { found(i,a+1,a+1,2); } if(d[i][a][b][k]<d[i][a+1][a+1][2]+p[a+1].y) { d[i][a][b][k]=d[i][a+1][a+1][2]+p[a+1].y; } } if(check(p[b],k,p[a+1].y,p[a+1].z)) { if(d[i][a+1][a+1][3]==-1) { found(i,a+1,a+1,3); } if(d[i][a][b][k]<d[i][a+1][a+1][3]+p[a+1].x) { d[i][a][b][k]=d[i][a+1][a+1][3]+p[a+1].x; } } //弃置不用 if(d[i][a+1][b][k]==-1) { found(i,a+1,b,k); } if(d[i][a][b][k]<d[i][a+1][b][k]) { d[i][a][b][k]=d[i][a+1][b][k]; } } int main() { scanf("%d %d",&n,&m); int i; for(i=1;i<=n;i++) { scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].z); } init(); found(0,0,0,0); printf("%d\n",d[0][0][0][0]); return 0; }