zoukankan      html  css  js  c++  java
  • 生日礼物(京东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;
        }
    
    
    }
    

      

  • 相关阅读:
    vim的分屏功能
    vim进阶
    VIM常用快捷键
    vim操作:打开多个文件、同时显示多个文件、在文件之间切换
    vim 如何复制文件中多行到另一个文件
    无限分类左右值算法的常规操作逻辑
    js查看Object对象的内容
    js获取当前页面的url信息
    javascript获取url中的参数值
    解决Eclipe安装不上android的ADT的办法
  • 原文地址:https://www.cnblogs.com/dshn/p/8619241.html
Copyright © 2011-2022 走看看