生日礼物(京东2016实习生真题)(最长递增子序列,输出长度和序列)


BF的生日快到了,这一次,小东决定为BF送一份特别的生日礼物为其庆生。作为高智商中的佼佼者,BF在国外求学,因此小东无法与之一起庆生。小东计划送一个生日卡片,并通过特别的包装让BF永远难忘。

 

她决定把卡片套装在一系列的信封A = {a1,  a2,  ...,  an}中。小东已经从商店中购买了很多的信封,她希望能够用手头中尽可能多的信封包装卡片。为防止卡片或信封被损坏,只有长宽较小的信封能够装入大些的信封,同尺寸的信封不能套装,卡片和信封都不能折叠。

 

小东计算了邮寄的时间,发现她的时间已经不够了,为此找你帮忙包装,你能帮她吗?

 

输入

 

输入有若干组,每组的第一行包含三个整数n, w, h,1<=n<=5000, 1<=w, h<=10^6,分别表示小东手头的信封数量和卡片的大小。紧随其后的n行中,每行有两个整数wi和hi,为第i个信封的大小,1<=wi, hi<=10^6。

 

样例输入

 

2 1 1

2 2

2 2

3 3 3

5 4

12 11

9 8

 

 

输出

 

对每组测试数据,结果第一行中输出最多能够使用的信封数量,结果第二行中按使用顺序输出信封的编号。由于小东有洁癖,她对排在前面的信封比较有好感,若有多个信封可用,她喜欢用最先拿到的信封。另外别忘了,小东要求把卡片装入能够装的最小信封中。

如果卡片无法装入任何信封中,则在单独的行中输出0。

 

 

样例输出

 

1

1

3

1 3 2

 

 

时间限制

C/C++语言:1000MS

其他语言:3000MS

内存限制

C/C++语言:65536KB

其他语言:589824KB

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n,w,h;
struct node
{
    int num;
    int w;
    int h;
} nodes[5005];

bool cmp(node a,node b)
{
    return a.w<b.w;
}
//最长递增子序列(输出长度和序列)
int maxs;
int lists[5005];
int LISS(int len)
{
    int dp[5005];
    int pre[5005];
    int maxs=1;
    int k=1;  //记录最后一个尾元素的位置
    for(int i=1;i<=len;i++)
    {
        pre[i]=i;  //开始的地方
        dp[i]=1;   //递增的长度
        for(int j=1;j<i;j++)
        {
            if(nodes[i].h>nodes[j].h&&dp[i]<dp[j]+1)
            {
                dp[i]=dp[j]+1;
                pre[i]=j;   //递增开始的地方
            }
        }
        if(dp[i]>maxs)
        {
            maxs=dp[i];
            k=i;
        }
    }
    int j=maxs;
    while(k!=pre[k])
    {
        lists[j--]=nodes[k].num;
        k=pre[k];
    }
    lists[j]=nodes[k].num;
    return maxs;
}

int main()
{
    while(~scanf("%d",&n))
    {
        maxs=1;
        int x,y;
        int g=0;
        cin>>w>>h;
        for(int i=1; i<=n; i++)
        {
            cin>>x>>y;
             if(x<=w||y<=h) continue;
                nodes[++g].w=x;
                nodes[g].h=y;
                nodes[g].num=i;
        }
        if(g==0)
        {
            cout<<"0"<<endl;
            continue;
        }
        
        sort(nodes+1,nodes+g+1,cmp);
        
        int maxs=LISS(g);
        int cas[5005];

        int ww=0;  //标记上一个进入递增序列的w值,用来筛掉后面w相同且符合递增的h
        int l=0;
        int ii,jj;
        for(ii=1;ii<=maxs;ii++)
        {
            for(jj=1;jj<=g;jj++)
            {
                if(lists[ii]==nodes[jj].num)
                    break;
            }


        if(nodes[jj].w!=ww)
        {

            cas[++l]=lists[ii];
            ww=nodes[jj].w;

        }
        }
        cout<<l<<endl;
        for(int i=1; i<l; i++)
        {
            cout<<cas[i]<<" ";
        }
        cout<<cas[l]<<endl;
    }


}

  

posted @ 2018-03-21 20:04  Lincy*_*  阅读(419)  评论(0编辑  收藏  举报