zoukankan      html  css  js  c++  java
  • D. Mysterious Present DAG dp

    https://codeforces.com/problemset/problem/4/D

    这个题目比较简单,就是一个DAG模型,这个可以看看紫书学习一下,

    我这次是用dp来写的,用记忆化搜索也许更好写一点。

    这个首先进行建图,用一个邻接表建图,G[i][j]表示第i个信封可以装进去第j个信封,这个再建图之前需要排序。

    不然的话就不好写这个dp了,其实这里有一点点不太能理解。

    建完图之后就是dp的转移,

    dp[i]表示从第i个信封开始可以装的最多的信封

    状态转移就是 d[i]=dp[j]+1

    这个之后就是路径的输出,这个路径输出需要好好理解,

    第一个就是怎么找到第一个数值,这个是一个for循环找到一个dp[i]==ans 

    然后就是递归找答案。

    这个递归需要break,这个自行理解吧。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<vector>
    #define inf 0x3f3f3f3f
    #define debug(x) cout<<"-----"<<" x = "<<x<<"-----"<<endl
    using namespace std;
    typedef long long ll;
    const int maxn = 5e3 + 10;
    struct node
    {
        int x, y, id;
        node(int x=0,int y=0):x(x),y(y){}
    }a[maxn];
    
    bool cmp(node a,node b)
    {
        return a.x < b.x;
    }
    int n, w, h;
    bool G[maxn][maxn];
    void build()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if (a[i].x > a[j].x&&a[i].y > a[j].y&&a[j].x > w&&a[j].y > h)
                {
                    G[i][j] = 1;
                }
                if (a[i].x > w&&a[i].y > h) G[i][0] = 1;
            }
        }
    }
    int dp[maxn];//表示从第i个可以嵌套的数量
    
    void print_ans(int i)
    {
        for (int j = 1; j <= n; j++)
        {
            if (G[i][j] && dp[i] == dp[j] + 1)
            {
                print_ans(j);
                break;
            }
        }
        printf("%d ", a[i].id);
    }
    
    int main()
    {
        scanf("%d%d%d", &n, &w, &h);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a[i].x, &a[i].y), a[i].id = i;
        }
        sort(a + 1, a + 1 + n, cmp);
        build();
        int ans = 0;
        memset(dp, 0, sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            if(G[i][0]) dp[i] = 1;
            for(int j=1;j<=i;j++)
            {
                if (G[i][j]&&G[i][0]) dp[i] = max(dp[i], dp[j]+1);
            }
            ans = max(dp[i], ans);
        }
        printf("%d
    ", ans);
        int b = 0;
        for (int i = 1; i <= n; i++) if (dp[i] == ans&&G[i][0]) b = i;
        if(b) print_ans(b);
        return 0;
    }
  • 相关阅读:
    GridView“GridView1”激发了未处理的事件“RowDeleting”
    遮罩层提示框,可拖动标题栏(兼容FF)
    JS判断IE,FF等浏览器类型
    DataGrid GridView 隔行换色 鼠标经过改变背景色
    常用js函数Common.js
    GridView和DataFormatString 日期格式 精确小数点后位数
    常用js函数CheckData.js
    图像处理技术
    VS Code中编写html(5) 标签的布局设置
    产品经理应该具备的技能(1)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10904513.html
Copyright © 2011-2022 走看看