Codeforces 4D

CF这套题目确实水啊,这题把每个信封能套进去的信封n方扫一遍,然后连一条有向边。由于一个信封不可能直接或间接地套在自己身上,因此这个图是一个DAG(有向无环图)。设f(i)表示从节点0开始的最多的矩形嵌套,就变成了求DAG上最长路的水题。f(i)=max(f(i),f(v)|(i,v)属于E)E是边集。

这坑爹题我交了两遍,第一次MLEon32,一看就是Vector爆了,考虑到只有5000个信封,果断short开起,然后就一半多一点的内存A了,辛亏不用写邻接表。

记录方案的话设一个from(i)表示i是由哪个推过来的,迭代输出就行了。

伏地%__debug大神。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
const int MAXN=5005;
struct card{
    int w,h;
}Karte[MAXN];
int n,dp[MAXN],from[MAXN];
std::vector<short> G[MAXN];
void add(short a,short b)
{
    G[a].push_back(b);
}
int Memorized_Search(short u)
{
    if(dp[u])return dp[u];
    if(!G[u].size())
    {
        dp[u]=0;
        return 0;
    }
    int& ans=dp[u];
    for(int i=0;i<G[u].size();i++)
    {
        int k=Memorized_Search(G[u][i])+1;
        if(dp[u]<k)
        {
            dp[u]=k;
            from[u]=G[u][i];
        }
    }
    return dp[u];
}
int main()
{
    scanf("%d",&n);
    scanf("%d %d",&Karte[0].w,&Karte[0].h);
    
    for(int i=1;i<=n;i++)
        scanf("%d %d",&Karte[i].w,&Karte[i].h);
    for(int i=0;i<=n;i++)
    {
        int x=Karte[i].w,y=Karte[i].h;
        for(int j=0;j<=n;j++)if(i!=j)
        {
            int a=Karte[j].w,b=Karte[j].h;
            if(x<a&&y<b)add(i,j);
        }
    }
    memset(dp,0,sizeof(dp));
    Memorized_Search(0);
    int root=from[0];
    printf("%d\n",dp[0]);
    while(root)
    {
        printf("%d ",root);
        root=from[root];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值