zoukankan      html  css  js  c++  java
  • UVa 103 Stacking Boxes --- DAG上的动态规划

      

      UVa 103

      题目大意:给定n个箱子,每个箱子有m个维度,

           一个箱子可以嵌套在另一个箱子中当且仅当该箱子的所有的维度大小全部小于另一个箱子的相应维度,

           (注意箱子可以旋转,即箱子维度可以互换),求最多能套几个箱子。

           第一行输入为n,m,之后是n行m维的箱子

      解题思路:嵌套关系是二元关系,因此这题即在DAG上做动态规划,

           只不过将二维的判断改成了n维,其他不变。

           详细看考:DAG上的动态规划之嵌套矩形  (ps:这题可以理解成嵌套m边形)

    /* UVa 103 Stacking Boxes --- DAG上的动态规划 */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int n, m;    //n为结点数,m为维度(n <= 30, m <= 10)
    int G[35][35];    //DAG, G[i][j]为1表示 盒子i可以嵌套在盒子j中
    int vec[35][15];
    int dp[35];
    
    //判断x是否小于y
    bool is_small(int x, int y){
        for (int i = 1; i <= m; ++i){
            //有一个大于等于则返回0
            if (vec[x][i] >= vec[y][i]){
                return 0;
            }
        }//for(i)
        return 1;
    }
    
    void CMAX(int&x, int y){
        if (y > x){
            x = y;
        }
    }
    
    int DP(int i){
        int &ans = dp[i];
        if (ans > 0){
            //记忆化搜索,避免重复计算
            return ans;
        }
        ans = 1;
        for (int j = 1; j <= n; ++j){
            if (G[i][j]){
                //递归求解
                CMAX(ans, DP(j) + 1);
            }
        }//for(j)
        return ans;
    }
    
    //输出序列
    void print_ans(int i){
        if (dp[i] == 1){
            //最后一个节点了
            printf("%d", i);
        }
        else{
            for (int j = 1; j <= n; ++j){
                if (G[i][j] && dp[j] + 1 == dp[i]){
                    printf("%d ", i);
                    print_ans(j);
                    break;
                }    
            }//for(j)    
        }
    }
    
    int main()
    {
    #ifdef _LOCAL
        freopen("D:\input.txt", "r", stdin);
    #endif
        while (scanf("%d%d", &n, &m) == 2){
            for (int i = 1; i <= n; ++i){
                for (int j = 1; j <= m; ++j){
                    scanf("%d", vec[i] + j);
                }//for(j)
                sort(vec[i] + 1, vec[i] + m + 1);
            }//for(i)
            
            //建DAG
            memset(G, 0, sizeof G);
            for (int i = 1; i <= n; ++i){
                for (int j = 1; j <= n; ++j){
                    //G[i][j]为1表示盒子i可以嵌套在盒子j中
                    if (is_small(i, j)){
                        G[i][j] = 1;    
                    }
                }//for(j)
            }//for(i)
    
            //求最长路径
            int ans = 0;
            int best;
            memset(dp, 0, sizeof dp);
            for (int i = 1; i <= n; ++i){
                if (DP(i) > ans){
                    ans = dp[i];
                    best = i;
                }
            }//for(i)
            printf("%d
    ", ans);
            print_ans(best);
            printf("
    ");
        }//while(scanf)
    
        return 0;
    }
    View Code

           

  • 相关阅读:
    【问题记录】IIS配置项
    Dapr可观测性
    es6 set方法使用
    js 数据类型
    获取到select下的所有option的文字和值
    使用js的webrtc进行sip协议连接,实现webrtc与电话网打通
    Qt (QGis) 中动态布局例子
    Latex中使注脚首行不缩进,且新行与首行对齐
    [转] 控制域的更新方式_小强office
    访问被屏蔽的FTP网站
  • 原文地址:https://www.cnblogs.com/tommychok/p/5361847.html
Copyright © 2011-2022 走看看