標籤:lis
連結:UVa 103
題意:給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;}