l i n k : link: link:题目链接
D
e
s
c
r
i
p
t
i
o
n
:
Description:
Description:
嵌套矩阵问题。给你若干矩阵,取出ans个,要求这ans个矩阵都严格大于给定矩阵,且这ans个矩阵可以嵌套。问,ans最大是多少,并且输出取出的矩阵的下标。
S
o
l
u
t
i
o
n
:
Solution:
Solution:
这是DAG最长路的问题,如果矩阵a可以嵌套在矩阵b中,就从a连一条有向边到b,问题就转化成求DAG最长路,且输出路径信息。DAG最长路的求法有很多,其中一种就是topsort。但是这题可以转化为LIS+sort。我们先排序一下,然后设
d
p
[
i
]
=
m
a
x
(
d
[
j
]
∣
j
dp[i] = max(d[j] | j
dp[i]=max(d[j]∣j 可以嵌套在i中 &&
j
<
i
)
j<i)
j<i),并且用一个pre数组保存$d[i]&由前面的哪个位置转移来的。那么最终答案就是max(d[i]),递归输出pre数组。
LIS+sort 代码:
#include <bits/stdc++.h>
#define pi pair<int,int>
#define mk make_pair
#define ll long long
#define pb push_back
using namespace std;
const int maxn = 5e3+100;
struct node {
int chang,kuang;
int id;
bool operator < (const node & t)const {
return (chang == t.chang&&kuang < t.kuang) || (chang < t.chang);
}
}a[maxn];
int pre[maxn],d[maxn];
void dfs(int pp)
{
if(pre[pp]!=0)dfs(pre[pp]);
printf("%d ",pp);
}
int main()
{
int n,cc,kk,flag = 0;
scanf("%d%d%d",&n,&cc,&kk);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].chang,&a[i].kuang);
if(a[i].chang > cc && a[i].kuang > kk)flag = 1;
a[i].id = i;
}
if(flag == 0)
{
puts("0");
return 0;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(a[i].chang <= cc || a[i].kuang <= kk)continue;
int tmp = 0;
for(int j=1;j<i;j++)
{
if(a[i].chang <= a[j].chang || a[i].kuang <= a[j].kuang)continue;
if(d[j] > tmp)
{
tmp = d[j];
pre[a[i].id] = a[j].id;
}
}
d[i] = tmp + 1;
}
int ans = 0,Id;
for(int i=1;i<=n;i++)
{
if(d[i] > ans)
{
ans = d[i];
Id = a[i].id;
}
}
cout<<ans<<'\n';
dfs(Id);
return 0;
}
topsort 代码(超空间但思路没问题的代码):
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn = 5005;
struct node {
int chang,kuang,id;
}a[maxn];
int pre[maxn],d[maxn],dp[maxn],n,lic,lik;;
vector<node>G[maxn];
void dfs(int ID)
{
if(pre[ID]!=0)dfs(pre[ID]);
printf("%d ",ID);
}
void topsort()
{
queue<int>q;
for(int i=1;i<=n;i++)
{
if(a[i].chang <= lic || a[i].kuang <= lik)continue;
if(!d[i])q.push(i),dp[i] = 1,pre[i] = 0;
}
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i=0;i<G[u].size();i++)
{
int v = G[u][i].id;
if(dp[v] < dp[u]+1)
{
dp[v] = dp[u] + 1;
pre[v] = u;
}
if(--d[v]==0)q.push(v);
}
}
int ans = 0,ID;
for(int i=1;i<=n;i++)
{
if(dp[a[i].id] > ans)
{
ans = dp[a[i].id];
ID = a[i].id;
}
}
printf("%d\n",ans);
dfs(ID);
}
int main()
{
scanf("%d%d%d",&n,&lic,&lik);
int flag = 0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].chang,&a[i].kuang);
if(a[i].chang > lic && a[i].kuang > lik)flag = 1;
a[i].id = i;
}
if(!flag)
{
puts("0");
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(a[i].chang <= lic || a[i].kuang <= lik)continue;
if(a[j].chang <= lic || a[i].kuang <= lik)continue;
if(a[i].chang < a[j].chang && a[i].kuang < a[j].kuang)
G[i].pb(a[j]),d[j]++;
}
topsort();
return 0;
}