UVa 103 Stacking Box(记忆化搜索)

题意:

有n个箱子,每个箱子有m的维度,箱子a能装到箱子b里面的条件是,存在一个序列,使a的任意一个维度大小小于b。

求最多能套几层箱子。

思路:

简单题。首先对每个箱子的维度从小到大排序,然后根据a和b的关系生成一个有向图无环图,然后进行遍历每个节点最大的值。

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <vector>

#include <algorithm>



using namespace std;



int n, m;

int a[35][20];

vector<int> map[35];

int dp[35], path[35];



bool judge(int p, int q)

{

    for (int i = 0; i < m; ++i)

        if (a[p][i] >= a[q][i])

            return false;

    return true;

}



int dfs(int u)

{

    if (dp[u])

        return dp[u];



    for (int i = 0; i < map[u].size(); ++i)

    {

        int v = map[u][i];

        int t = dfs(v) + 1;

        if (dp[u] < t)

            dp[u] = t, path[u] = v;

    }

    return dp[u];

}



int main()

{

    while (scanf("%d %d", &n, &m) != EOF)

    {

        for (int i = 1; i <= n; ++i)

        {

            for (int j = 0; j < m; ++j)

                scanf("%d", &a[i][j]);

            sort(a[i], a[i] + m);

            map[i].clear();

        }



        for (int i = 1; i <= n; ++i)

            for (int j = 1; j <= n; ++j)

                if (judge(i, j))

                    map[i].push_back(j);

        

        int ans = 0;

        memset(dp, 0, sizeof(dp));

        int id;

        for (int i = 1; i <= n; ++i)

        {

            int temp = dfs(i);

            if (ans < temp)

                ans = temp, id = i;

        }

        printf("%d\n", ans + 1);

        printf("%d", id);

        for (int i = 0; i < ans; ++i)

            id = path[id], printf(" %d", id);

        printf("\n");

    }

    return 0;

}

你可能感兴趣的:(stack)