uva--103--Stackint Boxes
Problem : 给你n个m维的多边形,当初存在一个顺序,使得两个多边形中的一个多边形的每条边都小于另一个
多边形,就说这个多边形能嵌套在另一个多边形里面,求最多存在多少个这样的连续的多边形使得s1>>s2>>...>>sn;
Way: 动态规划:把每个多边形看成一个点,当一个多边形能嵌套在另一个中,则连一条有向边,则变成了找有向图
的最长路径,dp[i]表示从i出发的最长的路径,则max(dp[i] | 1<=i<=n)则是最终答案,dp[i] = max(dp[i], dp[j]+1)(j指和i相邻的
多边形);
//
// main.cpp
// Calmeii
//
// Created by Calmeii on 14-5-5.
// Copyright (c) 2014年 apple. All rights reserved.
//
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 31
int G[MAXN][MAXN], val[MAXN][MAXN], dp[MAXN], n;
int dfs(int i)
{
if (dp[i] > 0){ //表示已经求过,直接返回即可
return dp[i];
}
dp[i] = 1;
for (int j = 1; j <= n; j++){
if (G[i][j]){
dp[i] = max(dfs(j)+1, dp[i]);
}
}
return dp[i];
}
int first;
void print_ans(int i)
{
if (first) first = 0;
else printf(" ");
printf("%d", i);
for (int j = 1; j <= n; j++){
if (G[i][j] && dp[i] == dp[j] + 1){
print_ans(j);
break;
}
}
}
int main()
{
int m;
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i++){
for (int j = 0; j < m; j++){
scanf("%d", &val[i][j]);
}
sort(val[i], val[i]+m);
}
memset(G, 0, sizeof(G));
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
int k;
for (k = 0; k < m; k++){
if (val[i][k] >= val[j][k]){ //表示不能构成边
break;
}
}
if (k == m){
G[i][j] = 1; //表示i到j存在有向边
}
}
}
int ans = 0; //保存最大的值
for (int i = 1; i <= n; i++){
ans = max(ans, dfs(i));
}
printf("%d\n", ans);
for (int i = 1; i <= n; i++){
if (ans == dp[i]){
first = 1;
print_ans(i);
break; //只需打印一种情况
}
}
printf("\n");
}
return 0;
}