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;
}
posted @ 2012-11-11 11:33  kedebug  阅读(283)  评论(0编辑  收藏  举报