/* Author: ACboy Date: 2010-5-19 Result: AC Descripition: UVa 103 Stacking Boxes */ #include <iostream> #include <algorithm> using namespace std; //邻接矩阵 int g[40][40]; //记录每条边 int edg[35][15]; //dp数组 int d[40]; //用来保存结果 int res[40]; //最长的路径的长度 int c; int k, n; int if_edg(int a, int b) { int i; int ok = 1; for (i = 1; i <= n; i++) { if (edg[a][i] >= edg[b][i]) { ok = 0; break; } } return ok; } // 记忆化搜索(DP) int dp(int i) { int &ans = d[i]; if (ans > 0) { return ans; } ans = 1; for (int j = 1; j <= k; j++) { if (g[i][j]) { if (dp(j) + 1 > ans) { ans = dp(j) + 1; } } } return ans; } // 根据d[]计算出结果并保存在res中。 void find_ans(int i) { res[c++] = i; for (int j = 1; j <= k; j++) { if (g[i][j] && d[i] == d[j] + 1) { find_ans(j); break; } } } int main() { #ifndef ONLINE_JUDGE freopen("103.txt", "r", stdin); #endif while (cin >> k >> n) { int i, j; for (i = 1; i <= k; i++) { for (j = 1; j <= n; j++) { cin >> edg[i][j]; } sort(edg[i] + 1, edg[i] + n + 1); } memset(g, 0, sizeof(g)); for (i = 1; i <= k; i++) { for (j = 1; j <= k; j++) { if (if_edg(i, j)) { g[i][j] = 1; } } } memset(d, 0, sizeof(d)); for (i = 1; i <= k; i++) { dp(i); } int max = -1; int pos = -1; for (i = 1; i <= k; i++) { if (d[i] > max) { max = d[i]; pos = i; } } cout << max << endl; c = 0; find_ans(pos); for (i = 0; i < c - 1; i++) { cout << res[i] << " "; } cout << res[c - 1] << endl; } return 0; }