矩阵嵌套问题

题意:有n个矩阵,每个矩阵可以用两个整数a、b描述,表示它的长和宽。矩阵X(a,b)可以嵌套在矩形Y(c,d)中,当且仅当a<c,b<d,或者b<c,a<d。输出最多嵌套的矩阵个数。

思路:如果矩阵X可以被Y嵌套,则相当于X到Y有一条路径,问题就转化成了在有向无环图中找最长路的问题。

      这个问题是动态规划的基础问题。这里用动态规划解决:

      设len(i)表示从结点i出发的最长路径长度。状态转移方程为:

      len(i) = max{len(j)+1|(i,j)∈E}

      E是边集。

实现:先把n个矩阵处理成一个邻接矩阵。

      然后用记忆化搜索的方法实现动态规划方程。

输入:

10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2

输出:  

   5

#include<iostream>
#include<memory.h>
using namespace std;

int gra[100][100];
int len[100];//从该点开始的最长路径长度
int n;

struct mat
{
    int a,b;
};

int f(int pos)
{
    if(len[pos] > 0)
    {
        return len[pos];
    }
    len[pos] = 1;
    for(int i = 0; i < n; i ++)
    {
        if(gra[pos][i])
        {
            len[pos] = max(len[pos], f(i) + 1);
        }
    }
    return len[pos];
}

int main()
{
    int ans = -1;
    cin >> n;
    mat nod[100];
    memset(gra, 0, sizeof(gra));
    memset(len, 0, sizeof(len));
    for(int i = 0; i < n; i ++)
    {
        cin >> nod[i].a >> nod[i].b;
    }
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if((nod[i].a < nod[j].a && nod[i].b < nod[j].b) || (nod[i].a < nod[j].b && nod[i].b < nod[j].a))
            {
                gra[i][j] = 1;
            }
        }
    }
    /*
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            cout << gra[i][j] << ' ';
        }
        cout << endl;
    }
    */
    for(int i = 0; i < n; i ++)
    {
        ans = max(ans, f(i));
    }
    cout << ans << endl;
    return 0;
}

 打印矩阵编号字典序最小的:

 

#include<iostream>
#include<memory.h>
using namespace std;

int gra[100][100];
int len[100];//从该点开始的最长路径长度
int n;

struct mat
{
    int a,b;
};

int f(int pos)
{
    if(len[pos] > 0)
    {
        return len[pos];
    }
    len[pos] = 1;
    for(int i = 0; i < n; i ++)
    {
        if(gra[pos][i])
        {
            len[pos] = max(len[pos], f(i) + 1);
        }
    }
    return len[pos];
}

void print(int i)
{
    cout << i << ' ';
    for(int j = 0; j < n; j ++)
    {
        if(gra[i][j] && len[i] == len[j] + 1)
        {
            print(j);
            break;
        }
    }
}

int main()
{
    int ans = -1;
    cin >> n;
    mat nod[100];
    memset(gra, 0, sizeof(gra));
    memset(len, 0, sizeof(len));
    for(int i = 0; i < n; i ++)
    {
        cin >> nod[i].a >> nod[i].b;
    }
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if((nod[i].a < nod[j].a && nod[i].b < nod[j].b) || (nod[i].a < nod[j].b && nod[i].b < nod[j].a))
            {
                gra[i][j] = 1;
            }
        }
    }
    int matid = 0;
    for(int i = 0; i < n; i ++)
    {
        if(f(i) > ans)
        {
            ans = f(i);
            matid = i;
        }
    }
    cout << ans << endl;
    print(matid);
    return 0;
}

 

 

 

     

 

posted @ 2017-10-26 22:49  哲贤  阅读(1353)  评论(0编辑  收藏  举报