题目链接:http://codeforces.com/problemset/problem/264/B
题目大意:
给出n个单调递增的数,让你找出最长的好序列,好序列是一种单调递增的并且相邻元素的最大公因数>1的子序列.
解题思路:
设dp[x]表示以x为结尾的好序列的最长长度。
d[i]表示以i为因子的x中最大的dp[x]值。
于是得到状态转移方程dp[x]=max(dp[x],d[i]+1) (i是x的因子)
每次求出dp[x]还要顺便更新d[i],即d[i]=dp[x].
代码:
1 #include<bits/stdc++.h> 2 #define lc(a) (a<<1) 3 #define rc(a) (a<<1|1) 4 #define MID(a,b) ((a+b)>>1) 5 #define fin(name) freopen(name,"r",stdin) 6 #define fout(name) freopen(name,"w",stdout) 7 #define clr(arr,val) memset(arr,val,sizeof(arr)) 8 #define _for(i,start,end) for(int i=start;i<=end;i++) 9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); 10 using namespace std; 11 typedef long long LL; 12 const int N=1e5+5; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-10; 15 16 vector<int>fat[N]; 17 int a[N],d[N],dp[N]; 18 19 int main(){ 20 FAST_IO; 21 int n; 22 cin>>n; 23 for(int i=1;i<=n;i++){ 24 cin>>a[i]; 25 }
//筛法求因子 26 for(int i=2;i<=a[n];i++){ 27 for(int j=i;j<=a[n];j+=i){ 28 fat[j].push_back(i); 29 } 30 } 31 32 int ans=0; 33 for(int i=1;i<=n;i++){ 34 //遍历因子 35 for(int j=0;j<fat[a[i]].size();j++){ 36 int t=fat[a[i]][j]; 37 dp[i]=max(dp[i],d[t]+1); 38 } 39 for(int j=0;j<fat[a[i]].size();j++){ 40 int t=fat[a[i]][j]; 41 d[t]=dp[i]; 42 } 43 ans=max(ans,dp[i]); 44 } 45 //只有1的时候ans为0,实际为1 46 cout<<max(ans,1)<<endl; 47 return 0; 48 }