首页 > 代码库 > codeforces 264 B. Good Sequences(dp+数学的一点思想)

codeforces 264 B. Good Sequences(dp+数学的一点思想)

题目链接:http://codeforces.com/problemset/problem/264/B

题意:给出一个严格递增的一串数字,求最长的相邻两个数的gcd不为1的序列长度

其实这题可以考虑一下素因数,将每一个数都已是分解为几个不重复的素数,设dp[i]为含有因数i的最长序列有多长

然后遍历一下这串数字,每次更新dp[a[i]]=max(dp[j]+1,dp[a[i]]),j表示a[i]的素因数,再将每个素因数更新为

最大值。

for(int i = 1 ; i <= n ; i++) {

        int gg = a[i] , flag = 0 , sum = 0;

        MAX = 0;

        for(int j = 0 ; j < cnt ; j++) {

            flag = 0;

            while(gg % num[j] == 0) {

                flag = 1;

                gg /= num[j];

            }

            if(flag == 1) {

                b[sum++] = num[j];

            }

            if(gg == 1)//不加这句会超时,因为最后当gg为1的时候就没有1以外的因数了再找下去就是浪费时间

                break;

        }

        for(int j = 0 ; j < sum ; j++) {

            MAX = max(dp[b[j]] + 1 , MAX);

        }

        for(int j = 0 ; j < sum ; j++) {

            dp[b[j]] = MAX;

        }

    }

 

#include <iostream>#include <cstring>#include <cmath>#include <cstdio>using namespace std;const int M = 1e5 + 10;int a[M] , b[M] , dp[M] , prime[M] , num[M] , cnt = 0;void IsPrime() {    prime[0] = prime[1] = 0 , prime[2] = 1;    for(int i = 3 ; i < M ; i++) {        prime[i] = i % 2 == 0 ? 0 : 1;    }    int t = (int)sqrt(M * 1.0);    for(int i = 3 ; i <= t ; i++) {        if(prime[i]) {            for(int j = i * i ; j < M ; j += 2 * i) {                prime[j] = 0;            }        }    }    for(int i = 2 ; i < M ; i++) {        if(prime[i]) {            num[cnt++] = i;        }    }}int main() {    int n;    IsPrime();    scanf("%d" , &n);    int count = 0 , MAX = 0;    for(int i = 1 ; i <= n ; i++) {        scanf("%d" , &a[i]);    }    memset(dp , 0 , sizeof(dp));    for(int i = 1 ; i <= n ; i++) {        int gg = a[i] , flag = 0 , sum = 0;        MAX = 0;        for(int j = 0 ; j < cnt ; j++) {            flag = 0;            while(gg % num[j] == 0) {                flag = 1;                gg /= num[j];            }            if(flag == 1) {                b[sum++] = num[j];            }            if(gg == 1)                break;        }        for(int j = 0 ; j < sum ; j++) {            MAX = max(dp[b[j]] + 1 , MAX);        }        for(int j = 0 ; j < sum ; j++) {            dp[b[j]] = MAX;        }    }    int MM = 1;    for(int i = 0 ; i < cnt ; i++) {        MM = max(dp[num[i]] , MM);    }    printf("%d\n" , MM);    return 0;}

codeforces 264 B. Good Sequences(dp+数学的一点思想)