uva103 - Stacking Boxes(动归,记忆化搜索)
利用条件建图,然后在图中找到最长路径,
状态:dp[i]表示以i为起点的最长路径长度。
状态转移:dp[i] = {max(dp[j]+1)|g[i][j] = 1}
代码如下:
#include <cstdio> #include <cstdlib> #include <cstring> #define M 15 #define N 35 int m, n, a[N][M], g[N][N], d[N]; int comp(const void *aa, const void *bb) { return *(int*)aa-*(int*)bb; } int judge(int s, int t) { for(int i = 0; i < m; i++) if(a[s][i]>=a[t][i]) return 0; return 1; } int dp(int x) { int &ans = d[x]; if(ans) return ans; ans = 1; for(int i = 1; i <= n; i++) { if(g[x][i]&&ans<dp(i)+1) ans = dp(i)+1; } return ans; } void print_ans(int x, int cur) { if(cur==1) {printf("%d\n",x); return; } else printf("%d ",x); for(int i = 1; i <= n; i++) if(g[x][i]&&d[x]==d[i]+1) {print_ans(i, cur-1); break;} } int main () { while(~scanf("%d %d",&n,&m)) { for(int i = 1; i <= n; i++) { for(int j = 0; j < m; j++) scanf("%d",&a[i][j]); qsort(a+i,m,sizeof(int),comp); } for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(i!=j&&judge(i,j)) g[i][j] = 1; else g[i][j] = 0; } memset(d,0,sizeof(d)); for(int i = 1; i <= n; i++) dp(i); int max = 1, maxl = 0; for(int i = 1; i <= n; i++) if(d[max]<d[i]) max = i; maxl = d[max]; printf("%d\n",maxl); print_ans(max,maxl); } return 0; }