UVa 103 Stacking Boxes --- DAG上的动态规划

Posted tan90丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n", ans);
        print_ans(best);
        printf("\\n");
    }//while(scanf)

    return 0;
}
View Code

 

       

以上是关于UVa 103 Stacking Boxes --- DAG上的动态规划的主要内容,如果未能解决你的问题,请参考以下文章

uva103-Stacking_Boxes

UVa 103 Stacking Boxes --- DAG上的动态规划

UVA11003 Boxes0-1背包

Uva12657 (Boxes in a Line)移动盒子

UVa 12525 Boxes and Stones (dp 博弈)

UVA 12657 Boxes in a Line