[CodeForces 566F] Clique in the Divisibility Graph (记忆化搜索)

来源:互联网 发布:电影院简单数据库设计 编辑:程序博客网 时间:2024/03/29 19:19

CodeForces - 566F
一个集合,如果其中两个数能一个能整除另一个,那么他们就具有双向的关系
问最大的相容集有多大

刚开始我把一个数之前有多少个因子存了下来
然后再枚举因子去求
编程复杂度爆炸,时间复杂度爆炸

后来才知道,其实反过来考虑就好了
dp[i] 表示第i个数之后有多少个以它为因子的
然后不断翻倍,判断其倍数是否在集合中
然后记忆化搜索即可

#include <cstdio>#include <iostream>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <map>#include <set>#include <queue>using namespace std;typedef pair<int,int> Pii;typedef long long LL;typedef unsigned long long ULL;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define Pow2(a) (a*a)const int maxn=1e6+10;int N,ans;int inpt[maxn];int pos[maxn];int dp[maxn];int DP(int,int);int main(){    scanf("%d\n", &N);    for(int i=1; i<=N; i++)    {        scanf("%d", &inpt[i]);        pos[inpt[i]]=i;    }    for(int i=1; i<=N; i++)    {        if(!dp[i])        {            DP(i,inpt[i]);        }        ans=max(ans,dp[i]);    }    printf("%d\n", ans);    return 0;}int DP(int np, int num){    if(dp[np]) return dp[np];    for(int i=2; (LL)i*num<maxn; i++)    {        if(pos[i*num])        {            dp[np]=max(dp[np], DP(pos[i*num], i*num)+1);        }    }    if(!dp[np]) dp[np]=1;    return dp[np];}
0 0
原创粉丝点击