UVA Live 6122 || UESTC OJ 2326 枚举+排序+LIS

来源:互联网 发布:mac版百度网盘 编辑:程序博客网 时间:2024/04/30 03:38

传送门:

UVALive

UESTC OJ

题意:有n个盒子,知道长宽高,将盒子堆起来,盒子可任意翻转,顺序任意,要求上面盒子的底面不能超出下面盒子的底面,问最多能堆多少个。

思路:首先n<=10,这就很容易想到枚举,我们在这里枚举每个盒子用哪个面做底面,这样的话最多是3^10种情况。这样枚举之后,我们得到了每个盒子的底面的两条边长:x1,y1;x2,y2;x3,y3;.........,我们这里让x<y,也就是底面变长较小的放在前面。然后对这些底面进行排序,x小的放前面,如果x一样,y小的放前面。这样排完序,对y序列找最长不下降子序列,最长的即是答案。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{    int l,w;} p[15],c[15];int a[15][4];int n,s[15];int x[3]= {0,0,1};int y[3]= {1,2,2};int ans;bool cmp(node xx,node yy){    if(xx.l==yy.l)return xx.w<yy.w;    else return xx.l<yy.l;}void dfs(int u){    if(u==n)    {        for(int i=0; i<n; i++)        {            c[i]=p[i];        }        sort(c,c+n,cmp);        memset(s,0,sizeof(s));        for(int i=0; i<n; i++)        {            s[i]=1;            for(int j=i-1; j>=0; j--)            {                if(c[i].w>=c[j].w&&s[i]<s[j]+1)                {                    s[i]=s[j]+1;                    if(ans<s[i])ans=s[i];                }            }        }        return;    }    for(int i=0; i<3; i++)    {        p[u].l=a[u][x[i]];        p[u].w=a[u][y[i]];        if(p[u].l>p[u].w)swap(p[u].l,p[u].w);        dfs(u+1);    }}int main(){    int ca=1;    while(scanf("%d",&n)&&n)    {        for(int i=0; i<n; i++)        {            scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);        }        ans=0;        dfs(0);        cout<<"Case "<<ca++<<": ";        cout<<ans<<endl;    }    return 0;}


原创粉丝点击