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

Posted 凌晨一点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生日礼物(京东2016实习生真题)(最长递增子序列,输出长度和序列)相关的知识,希望对你有一定的参考价值。

#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;
    }


}

 

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

以上是关于生日礼物(京东2016实习生真题)(最长递增子序列,输出长度和序列)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题 最长递增子序列

使用分而治之找到最长的递增子序列

笔试题1:最长严格递增子序列

最长递增子序列 && 最大子序列最长递增子序列最长公共子串最长公共子序列字符串编辑距离

2022华为机试真题 C++ 实现非严格递增连续数字序列

华为OD机试真题 Python 实现非严格递增连续数字序列