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);
}