UVA103

UVA 103

题意:

有 n 个盒子,每个盒子由 k 个元素表示,把盒子互相嵌套起来,
只有表示盒子的每个元素都大于另一个盒子的每个元素的时候才可以嵌套;元素间可以交换位置;
比如(5,1,3)可以放在 (2,4,6)里面。
问最多可以套多少个。

解题:

先把表示盒子的每个元素排序,再把每个盒子排序。用 LIS 求答案。

噫..盒子排序排了好久..傻了= =

 

#include<bits/stdc++.h>
using namespace std; 
struct node {
    int s,id;
    int num[25];
    bool operator < (const node &b) const {
        for(int i=1; i<=s; i++) {
            if(num[i] < b.num[i]) return true;
            if(num[i] > b.num[i]) return false;
        }
        return true;
    }    
    void nsort(){
        sort(num+1,num+1+s);
    }
}a[35];
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=k;j++) {
                scanf("%d",&a[i].num[j] );
                a[i].s = k; a[i].id = i;
            }
            a[i].nsort();        
        }
        sort(a+1,a+n+1);        
        int len = 1, d[35] = {0};
        int pre[35] = {0}, ed = 1;
        for(int i=0;i<35;i++) pre[i] = i;    
        for(int i=1;i<=n;i++) {
            d[i] = 1;
            for(int j=1;j<i;j++) {                    
                int ov = 0;
                for(int r=1;r<=k;r++) {
                    if(a[j].num[r] >= a[i].num[r]) {
                        ov = 1; break;
                    }
                }             
                if( (!ov) && (d[j]+1 > d[i]) ) {
                    d[i] = d[j] + 1;
                    pre[i] = j;
                    if(d[i] > len) {
                        len = d[i]; ed = i;
                    }
                }
            }
        } 
        int ans[35] = {0}, cnt = 0;
        while(ed != pre[ed]) {
            ans[cnt++] = a[ed].id;
            ed = pre[ed];
        } 
        ans[cnt] = a[ed].id; 
        printf("%d\n",len); 
        for(int i=cnt;i>0;i--)
            printf("%d ",ans[i]);
        printf("%d\n",ans[0]);
    }    
    return 0;
}

 

转载于:https://www.cnblogs.com/ember/p/5745928.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值