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;
}


 

你可能感兴趣的:(uva103 - Stacking Boxes(动归,记忆化搜索))