CodeForces 264B.Good Sequences(DP)

博客围绕Good Sequences问题展开,该问题要求找出满足严格递增、相邻元素不互质且元素为给定好整数的最长序列长度。给出了输入输出示例,采用动态规划(DP)方法求解,定义了dp[i]和d[i],每次转移完dp[x]后更新d[i]。

B. Good Sequences

(2s,256M)
Squirrel Liss is interested in sequences. She also has preferences of integers. She thinks nnn integers a1, a2, ..., ana_1, a_2, ..., a_na1,a2,...,an are good.

Now she is interested in good sequences. A sequence x1, x2, ..., xkx_1, x_2, ..., x_kx1,x2,...,xk is called good if it satisfies the following three conditions:

The sequence is strictly increasing, i.e. xi &lt; xi + 1x_i &lt; x_i + 1xi<xi+1 for each i(1 ≤ i ≤ k − 1)i (1 ≤ i ≤ k - 1)i(1ik1).
No two adjacent elements are coprime, i.e. gcd(xi, xi + 1) &gt; 1gcd(x_i, x_{i + 1}) &gt; 1gcd(xi,xi+1)>1 for each i(1 ≤ i ≤ k − 1)i (1 ≤ i ≤ k - 1)i(1ik1) (where gcd(p, q)gcd(p, q)gcd(p,q) denotes the greatest common divisor of the integers ppp and qqq).
All elements of the sequence are good integers.
Find the length of the longest good sequence.

Input
The input consists of two lines. The first line contains a single integer n(1 ≤ n ≤ 105)n (1 ≤ n ≤ 10^5)n(1n105) — the number of good integers. The second line contains a single-space separated list of good integers a1, a2, ..., ana_1, a_2, ..., a_na1,a2,...,an in strictly increasing order (1 ≤ ai ≤ 105;ai &lt; ai + 1)(1 ≤ a_i ≤ 10^5; a_i &lt; a_{i + 1})(1ai105;ai<ai+1).

Output
Print a single integer — the length of the longest good sequence.

Examples
input

5
2 3 4 6 9

output

4

input

9
1 2 3 5 6 7 8 9 10

output

4

Note
In the first example, the following sequences are examples of good sequences: [2;4;6;9],[2;4;6],[3;9],[6][2; 4; 6; 9], [2; 4; 6], [3; 9], [6][2;4;6;9],[2;4;6],[3;9],[6]. The length of the longest good sequence is 444.

Solution

DP
dp[i]dp[i]dp[i]表示以iii结尾的Good Sequence
d[i]d[i]d[i]表示所有含有iii这个质因子的xxxmax(dp[x])max(dp[x])max(dp[x])
每次转移完dp[x]dp[x]dp[x]之后,再更新一下所有的d[i]d[i]d[i]即可

Code

#include <cstdio>
#include <algorithm>
#define N 100010

using namespace std;

int a[N], dp[N], d[N];
int gcd(int x, int y) {
	if (y == 0) return x;
	else return(y, x % y);
}

int main() {
	int n;
	scanf("%d", &n);
	if (n == 1) {
		printf("%d\n", 1);
		return 0;
	}
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i) {
		int e = a[i];
		for (int j = 2; j * j <= a[i]; ++j) {
			if (e % j == 0) {
				dp[a[i]] = max(dp[a[i]], d[j]);
				while (e % j == 0) e /= j;
			}
		}
		if (e > 1) dp[a[i]] = max(dp[a[i]], d[e]);
		dp[a[i]]++;
		ans = max(ans, dp[a[i]]);
		e = a[i];
		for (int j = 2; j * j <= a[i]; ++j) {
			if (e % j == 0) {
				d[j] = dp[a[i]];
				while (e % j == 0) e /= j;
			}
		}
		if (e > 1) d[e] = dp[a[i]];
	}
	printf("%d\n", ans);
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值