链接:点击打开链接
题意:求树上的最长上升子序列长度
代码:
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
vector<int> G[6005];
int n,dp[6005],ans[6005],val[6005];
void dfs(int s,int fa,int rt){
int i,cp,pos,tmp;
for(i=0;i<G[s].size();i++){
tmp=G[s][i];
if(tmp==fa)
continue;
pos=lower_bound(dp,dp+n,val[tmp])-dp;
cp=dp[pos];
dp[pos]=val[tmp];
ans[rt]=max(ans[rt],lower_bound(dp,dp+n,INF)-dp);
dfs(tmp,s,rt);
dp[pos]=cp; //将更改过的点回溯回去
}
}
int main(){
int i,j,u,v,res;
while(scanf("%d",&n)!=EOF){
for(i=0;i<=n;i++)
G[i].clear();
for(i=1;i<=n;i++)
scanf("%d",&val[i]);
for(i=1;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++){ //就是枚举根节点,每次在树上进行lis
memset(dp,INF,sizeof(dp));
dp[0]=val[i];
dfs(i,0,i);
}
res=1;
for(i=1;i<=n;i++)
res=max(res,ans[i]);
printf("%d\n",res);
}
return 0;
}