小白上的例题,但是LRJ说要转化为DAG来做。
直接看了解题报告,这题有两种方法,一种是类似于求最长上升子序列,按矩形的长排序了,然后求。然后我发现我不会求最长上升子序列。。顺便补了一下。
还有一种就是转化DAG。。还在理解中。
-------------------------------------------------------------------------------------
根据每个矩形的嵌套关系,可以这样表示:如果矩形A可以嵌套在矩形B里面,mp[A] = B,也可以mp[A][B] = 1,不过后者需要的空间更多。在此我们采用前者。
然后就和图里面的找最长路径差不多。只是多了一步,记录沿着矩形A可以嵌套的最大值,这样如果之后需要数据的话就可以直接用了。
沿着图遍历,最后返回路径。
1.上升子序列
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1000 + 100;
struct POINT
{
int x, y;
friend bool operator < (const POINT &a, const POINT &b)
{
if (a.x != b.x)
return a.x < b.x;
else
return a.y < b.y;
}
}point[MAXN];
int main()
{
//freopen("input.txt", "r", stdin);
int T, n, i, j, a, b, ans;
int dp[MAXN];
scanf("%d", &T);
while (T--)
{
ans = 0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d%d", &a, &b);
point[i].x = min(a, b);
point[i].y = max(a, b);
}
sort(point, point + n);
dp[0] = 1;
for (i = 1; i < n; i++)
{
ans = 0;
for (j = 0; j < i; j++)
if (point[i].x != point[j].x && point[i].y > point[j].y && dp[j] > ans)
ans = dp[j];
dp[i] = ans + 1;
}
for (i = 0; i < n; i++)
ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return 0;
}
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1000 + 100;
struct POINT
{
int x, y;
}point[MAXN];
int dp[MAXN];
int DFS(int i, const vector<int> *mp)
{
int temp;
int &ans = dp[i];
if (ans > 0)
return ans;
ans = 1;
for (int j = 0; j < mp[i].size(); j++)
{
temp = DFS(mp[i][j], mp) + 1;
ans = max(ans, temp);
}
return ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
int T, i, j, n, a, b;
scanf("%d", &T);
while (T--)
{
memset(dp, 0, sizeof(dp));
vector<int> mp[MAXN];
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d%d", &a, &b);
point[i].x = min(a, b);
point[i].y = max(a, b);
}
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (point[i].x < point[j].x && point[i].y < point[j].y)
mp[i].push_back(j);
int ans = 0;
for (i = 1; i <= n; i++)
{
int temp = DFS(i, mp);
ans = max(temp, ans);
}
printf("%d\n", ans);
}
return 0;
}