大意是有一些n维的物体,他的边也是n条,如果将一个物体的边按任意顺序排列,只要有一种排列满足一一对应小于另一物体的边,就可以将这个物体嵌套进去另一个物体中,文最多能连续嵌套几个物体。
所求的最多的连续嵌套数与最长递增子序列相似,只不过一般的是单个数的比较,这里是一列数的比较。还有就是满足条件的嵌套的物体的编号用递归来求。
还可以记忆化搜索.
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int n,m,dp[32],s[32]; 8 bool vis[32][32]; 9 10 struct node{ 11 int num[32]; 12 int odr; 13 friend bool operator <(const node & x,const node & y) { 14 for (int i=1 ; i<=m ; i++) 15 if (x.num[i]>y.num[i]) return false; 16 return true; 17 } 18 }a[32]; 19 20 bool jjc(int x,int y) 21 { 22 for (int i=1 ; i<=m ; i++) 23 if (a[x].num[i]>=a[y].num[i]) return false; 24 return true; 25 } 26 27 void dfs(int i){ 28 if (i!=s[i]) dfs(s[i]); 29 printf("%d ",a[i].odr); 30 } 31 32 int main() 33 { 34 while (~scanf("%d%d",&n,&m)) 35 { 36 for (int i=1 ; i<=n ; i++){ 37 for (int j=1 ; j<=m ; j++){ 38 scanf("%d",&a[i].num[j]); 39 } 40 a[i].odr=i; 41 sort(a[i].num+1,a[i].num+m+1); 42 } 43 sort(a+1,a+n+1); 44 memset(vis,false,sizeof(vis)); 45 for (int i=1 ; i<=n ; i++){ 46 for (int j=i+1 ; j<=n ; j++){ 47 if (jjc(i,j)) vis[i][j]=true; 48 } 49 } 50 memset(dp,0,sizeof(dp)); 51 dp[1]=s[1]=1; 52 for (int i=2 ; i<=n ; i++){ 53 s[i]=i; 54 for (int j=1 ; j<i ; j++){ 55 if (vis[j][i]&&dp[i]<dp[j]+1) 56 dp[i]=dp[j]+1,s[i]=j; 57 } 58 } 59 int maxn=0,pos=1; 60 for (int i=1 ; i<=n ; i++) 61 if (maxn<dp[i]) maxn=dp[i],pos=i; 62 printf("%d\n",maxn); 63 dfs(pos); 64 printf("\n"); 65 } 66 return 0; 67 }