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
" , MM);
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6675028.html