CF1350B.Oral and Models(DP)

题意:

给出一个序列,请你找最长上升子序列,但要保证子序列里的从小到大的下标满足被整除的关系。

题解:

一开始一直tle,后来我的做法是从1到1e5预处理出每个数的因子,用邻接表存起来,然后就是最基本的上升子序列问题了。

#include<bits/stdc++.h>
 
using namespace std;
const int maxn=1e5+100;
int t;
int n;
int a[maxn];
int d[maxn];//表示最长上升子序列
vector<int> g[maxn];
int main () {
    cin>>t;
    for (int i=1;i<=maxn;i++) {
        for (int j=i;j<=maxn;j+=i) g[j].push_back(i);
    }
    while (t--) {
        cin>>n;
        for (int i=1;i<=n;i++) scanf("%d",&a[i]),d[i]=1;
        int Max=-1;
        for (int i=1;i<=n;i++) {
            for (int k=0;k<g[i].size();k++)
                if (a[g[i][k]]<a[i]) d[i]=max(d[i],d[g[i][k]]+1);
            Max=max(Max,d[i]);
        }
        printf("%d\n",Max);
    }
}

 

posted @ 2020-05-23 15:07  zlc0405  阅读(168)  评论(0编辑  收藏  举报