Code Forces #4 D

来源:互联网 发布:历史大非农数据准确率 编辑:程序博客网 时间:2024/04/27 17:16

一张卡片,要从n个信封中挑选若干来包裹它,信封也可以包裹信封

a能包裹b的条件是a的长宽均严格大于b的长宽。

给出信封个数n,卡片长宽,以及每个信封长宽,求出最多使用的信封数以及选择了哪些信封,没有则输出0;


不考虑卡片的时候可以把所有信封进行 长宽二级升序排,然后按最长递增子序列来求。

但是有卡片。

卡片必须装,而且必须是最小的一个。

可以先把卡片长宽l,r读进来,然后每读入一个信封的时候,把它的长-l,宽-r然后判断是否都均>0,满足再正常记录,否则不记录,但是id号正常记,这样可以筛掉不可能选择的信封,同时最后读完所有数据把卡片长宽改为0,这样就保证卡片一定是可选择里最小的。

最后注意卡片不算个数,也不要把卡片下标输出。


#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;struct node{    int l,r,vis,id;}a[5555];int cmp(node a,node b){    if(a.l==b.l)return a.r<b.r;    else return a.l<b.l;}int dp[5005];int f[5005];int ans[5005],tot=0;int main(){    int n;    while(scanf("%d",&n)!=EOF){        n++;        int ok=1;        scanf("%d %d",&a[0].l,&a[0].r);        for(int i=1;i<n;i++){            scanf("%d %d",&a[ok].l,&a[ok].r);            a[ok].l-=a[0].l,a[ok].r-=a[0].r;            a[ok].id=i;            if(a[ok].l<=0||a[ok].r<=0);            else ok++;        }        int mx=0,ed=-1;        memset(f,-1,sizeof(-1));        a[0].r=a[0].l=0;        sort(a,a+ok,cmp);        dp[0]=1;        for(int i=1;i<ok;i++){            dp[i]=1;            for(int j=0;j<i;j++){                if(a[j].l<a[i].l&&a[j].r<a[i].r&&dp[j]+1>dp[i]){                    dp[i]=dp[j]+1;                    f[i]=j;                    if(dp[i]>mx)mx=dp[i],ed=i;                }            }        }        if(mx==0){            printf("0\n");continue;        }        int now=ed;        while(now!=-1){            ans[tot++]=a[now].id,now=f[now];        }        printf("%d\n",mx-1);        for(int i=tot-2;i>=0;i--){            printf("%d ",ans[i]);        }        printf("\n");    }    return 0;}




0 0
原创粉丝点击