1334. 香樟树

Description

  被誉为江南四大名木之一的香樟树很有特色,它的树皮粗糙,质地却很均匀,从来没有白杨树的斑斑驳驳、没有柳树的肿瘤结节;树枝树干一分为二、二分为四一路长去,不会偷工减料也不会画蛇添足;树冠的形态是球形的,在天空中画出优美的曲线。
  除了上述优点之外,香樟树还有一个秘密武器。那就是……………………它凭借朴实、厚重的优秀品格赢得了小狐狸的青睐!!!
  话说有一天,小狐狸正在湖边散步,忽然一阵风吹来,她赶紧闭上眼睛。当她再次睁开眼睛时,发现美丽的湖畔多出了一排整齐的香樟树。小狐狸非常兴奋,她对每棵树都观察入微,并且数出了它们的叶子个数。她觉得如果相邻两棵树的叶子个数互素是不和谐的。因此小狐狸想从一排香樟树中选出若干棵,在满足相邻两棵树的叶子个数不互素的条件下,使得树尽量多。

Input

  第一行一个正整数n,表示有n棵香樟树。
  第二行n个正整数,第i个数表示第i棵香樟树叶子的个数。

Output

  一个正整数,表示最多能选多少棵树。

Sample Input

6
6 2 3 15 8 5

Sample Output

4

做法:考试的时候只能想到普通dp(变形后的最长不下降??)时间复杂度O(n^2),本来以为60结果才50.。。看了题解发现这题其实挺奇妙的,dp果然博大精深。。简单来说就是把读入的数质因数分解,显然如果两个数有相同的质因子就可以相连,于是我们想到用这个更新。。 时间复杂度。。O(n根号n)

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#define N 100007
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define LL long long
using namespace std;
int n, a[N], f[N], max_num;

int max(int a, int b){
    if (a > b)  return a;
    return b;
}

void divide(int x){
    int t = sqrt(x);
    int num = x;
    int len_max = 0;
    rep(i, 2, t){
        if (num == 1)   break;
        if (num % i == 0){
            len_max = max(f[i], len_max);
            while (num % i == 0)    num /= i;
        }
    }
    if (num != 1)   len_max = max(f[num], len_max);
    len_max++;
    num = x;
    rep(i, 2, t){
        if (num == 1)   break;
        if (num % i == 0){
            f[i] = max(f[i], len_max);
            while(num % i == 0)     num /= i;
        }
    }
    if (num != 1)   f[num] = max(f[num], len_max);
}

int main(){
    scanf("%d", &n);
    int s = 0;
    rep(i, 1, n) {
        scanf("%d", &s);
        max_num = max(s, max_num);
        divide(s);
    }
    int ans = 0;
    rep(i, 2, max_num){
        ans = max(ans, f[i]);
    }
    printf("%d", ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值