数列互质问题。


题目大意:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

给出一个数列,要求选出若干个数,这些数可以相邻也可以不相邻,这些数满足相邻的两个数不能互质,求最多有多少个数满足要求。【数列中1的情况是存在的】。数据范围:n<=100000,数列中的数<=100000

例如:给出6个数的数列:6,2,3,15,8,5,那么满足要求的解就是4,即6,3,15,5

解题思路:

首先用到了分解质因数:

朴素的分解质因数代码如下:【From 百度百科】

应该很好理解。

 1  var
2 n,i:longint;
3 begin
4 readln(n);
5 write(n,'=1');
6 i:=2;
7 while i<=n do begin
8 while n mod i=0 do begin
9 write('*',i);
10 n:=n div i;
11 end;
12 inc(i);
13 end;
14 end.

题目给出的数据范围为100000,我们用筛法求出100000以内的质数。

从前往后扫过数列,对于当前处理的数,当前位的前一个相邻的数一定与它不互质,也就是说如果想要求到当前位满足要求的最长序列,它的上一位一定是离它最近的且有公共质因子的数,由这个最近的数的长度+1来更新当前数位的长度。

设w[j]表示当前质因数能够整除前面数中的最后一个的位数。F[i]表示i位数满足要求的最长长度。其中第j个质数必须能够整除数列中第i个数。

样例的模拟过程:

数列:6 2 3 15 8 5

质数:2 3 5 7 11 13……

1.处理数列中第一个数6.不大于6的质数有2,3,都是6的质因数,由于在6的前面没有跟6的公共质因子为2或3的数,故更新f[1]:=1;w[1]:=1;w[2]:=1;【注意w[j]表示的是第j个质数】

2.处理数列中第二个数2,不大于2的质数有2,是2的质因数。2是第1个质数,w[1]=1,找到数列中的第一个数6,由f[1]来更新f[2],所以f[2]=f[1]+1=2

3.以此类推……

求出了数列中所有数的最长序列长度,最后总的扫描一遍求最大值即可。

代码如下:

 1 var
2 i,j,k,n,m:longint;
3 zhi,g,a,w:array[0..100001] of longint;
4 v:array[0..100001] of boolean;
5 sum,ans,tmp:longint;
6 procedure init;
7 begin
8 readln(n);
9 for i:=1 to n do
10 read(a[i]);
11 end;
12 procedure main;
13 begin
14 fillchar(v,sizeof(v),true);
15 for i:=2 to 50000 do
16 begin
17 j:=2;
18 while i*j<=100000 do
19 begin
20 v[i*j]:=false;
21 j:=j+1;
22 end;
23 end;
24 sum:=0;
25 for i:=2 to 100000 do
26 if v[i] then
27 begin
28 inc(sum);
29 zhi[sum]:=i;
30 end;
31 fillchar(g,sizeof(g),0);
32 for i:=1 to n do
33 if a[i]<>1 then
34 begin
35 for j:=1 to sum do
36 begin
37 if zhi[j]>a[i] then break;
38 if a[i] mod zhi[j]=0 then
39 begin
40 if g[w[j]]+1>g[i] then g[i]:=g[w[j]]+1;
41 w[j]:=i;
42 end;
43 end;
44 end;
45 ans:=0;
46 for i:=1 to n do
47 if g[i]>ans then ans:=g[i];
48 writeln(ans);
49 end;
50 begin
51 assign(input,'tree.in');reset(input);
52 assign(output,'tree.out');rewrite(output);
53 init;
54 main;
55 close(input);
56 close(output);
57 end.

Viaky原创。请勿copy。

转载于:https://www.cnblogs.com/Viaky/archive/2011/08/11/2135396.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值