最长不下降子序列-拓扑+dp
先水一个自己写的30%
·
https://www.luogu.com.cn/problem/P10287
1.a的范围就是一个提示点,提示我们用价值遍历
2.按经过节点先后顺序,所以在bfs实现拓扑序的实现dp
3.重点,不是入度为0的时候才dp,是因为可能是一条环
hack数据:
6 6
1 2 3 2 1 3
1 2
2 3
3 6
3 4
4 5
5 3
正确答案应该是3;
若在入度为0的时候ma=2,因为没考虑3
#include<bits/stdc++.h>
#include<string>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<int,int> pii;
queue<int> q;
vector<int> mp[N];
int d[N];
int n,m;
int dp[N][12];
vector<int> an;
int in[N];
int ma=0;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>d[i];
dp[i][d[i]]=1;
}
an.push_back(0);
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
in[y]++;
mp[x].push_back(y);
}
for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
while(q.size())
{
int t=q.front();
q.pop();
for(int i=0;i<mp[t].size();i++)
{
int v=mp[t][i];
in[v]--;
if(!in[v])
{
q.push(v);
}
///不是入度为0的点也参与
for(int j=1;j<=d[v];j++)///前i件,最后(即最大价值)为j的dp
dp[v][d[v]]=max(dp[t][j]+1,dp[v][d[v]]);///可以被d[v]更新
for(int j=1;j<=10;j++)///更新全部价值在i当前的最大
dp[v][j]=max(dp[v][j],dp[t][j]);
}
}
///遍历全部寻找最大
for(int i=1;i<=n;i++) for(int j=1;j<=10;j++) ma=max(dp[i][j],ma);
cout<<ma;
return 0;
}
更多推荐
所有评论(0)