题意:给n维图形,它们的边长是{d1,d2,d3...dn}, 对于两个n维图形,求满足其中一个的所有边长
按照任意顺序都一一对应小于另一个的边长,这样的最长序列的个数,并且打印任意一个最长子串的路径,
例如:a(9,5,7,3),b(6,10,8,2),c(9,7,5,1),a和b不满足,但c和b满足
分析:首先对没组边长从小到大排序,再对各组图形按最小边排序,再求最大子串,
对于打印路径,可以逆序循环,也可递归求解
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[35],path[35],num,m,k;
struct stu
{
int a[12],id;
}s[35];
int cmp(struct stu s1,struct stu s2)
{
return s1.a[1]<s2.a[1];
}
/*void back_path1(int i)
{
if(path[i]!=i)
back_path1(path[i]);
printf("%d",s[i].id);
num++;
if(num!=m)
printf(" ");
else
printf("\n");
}*/
/*void back_path2(int i)
{
if(k--){
back_path2(path[i]);
printf("%d",s[i].id);
num++;
if(num!=m)
printf(" ");
else
printf("\n");
}
}*/
int main()
{
int i,j,n,pos,b[1005];
while(scanf("%d%d",&m,&n)!=EOF){
for(i=1;i<=m;i++){
s[i].id=i;
for(j=1;j<=n;j++)
scanf("%d",&s[i].a[j]);
sort(s[i].a+1,s[i].a+n+1); //对每个图形的边长排序
}
sort(s+1,s+m+1,cmp); //对各个图形之间,按最小边长的大小排序
for(i=1;i<=m;i++){
dp[i]=1;
path[i]=i;
for(j=1;j<i;j++){
for(k=1;k<=n;k++)
if(s[j].a[k]>=s[i].a[k])
break;
if(k==n+1&&dp[j]+1>dp[i]){
dp[i]=dp[j]+1;
path[i]=j;
}
}
}
pos=1;
for(i=2;i<=m;i++)
if(dp[i]>dp[pos])
pos=i;
m=dp[pos];
printf("%d\n",m);
b[1]=s[pos].id; //先把最后一个编号加入
i=2;
for(j=pos-1;j>=1;j--){ //逆序循环求路径
for(k=1;k<=n;k++)
if(s[j].a[k]>=s[pos].a[k])
break;
if(k==n+1&&dp[j]+1==dp[pos]){
b[i++]=s[j].id;
dp[pos]--;
}
if(dp[pos]==1)
break;
}
for(j=i-1;j>1;j--)
printf("%d ",b[j]);
printf("%d\n",b[1]);
/*num=0; //递归方法1
back_path1(pos);*/
/*num=0; //递归方法2
k=m;
back_path2(pos);*/
}
return 0;
}