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;
}
posted @ 2012-08-03 21:31  willzhang  阅读(132)  评论(0编辑  收藏  举报