1. 程式人生 > >Codeforces Round #162 (Div. 1) B. Good Sequences (dp+分解素數)

Codeforces Round #162 (Div. 1) B. Good Sequences (dp+分解素數)

mes pro 題意 ack 位置 .com 但是 相同 判斷素數

題目:http://codeforces.com/problemset/problem/264/B

題意:給你一個遞增序列,然後找出滿足兩點要求的最長子序列

第一點是a[i]>a[i-1]

第二點 gcd(a[i],a[i-1])>1 也就是說兩個數不能互質

找出最長的子序列長度

思路:首先想互質問題,如果兩個數互質說明兩個數之間沒有素因子相同,我們想以每個素因子結尾的最大長度是多少

然後比如樣例 2 3 4 6 9

第一個數 2 2結尾 1

第二個數 3 3結尾 1

第三個數 4 2結尾 2

第四個數6 拆分因子有 2,3 2結尾 3, 3結尾2 ,但是這個時候我以6結尾,那麽其實3這個位置長度也是3了,

(所以,我們要找出最大的那個長度,再重新賦值到這個數的每個素因子上) 這個時候就能解出來了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<iostream>
#include<map>
#define mod 1000007
#define maxn 200001
using namespace std;
typedef long long ll;
ll a[maxn];
ll dp[maxn];
ll n;
int main(){ cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; } for(int i=0;i<n;i++){ ll z=a[i]; map<ll,ll> mp; vector<int> q; while(z!=1){ ll t=(ll)sqrt((double)z);//必須要加,不然會超時 ll j
=2; for(;j<=t;j++){ if(z%j==0){ if(mp[j]==0) q.push_back(j); mp[j]++; z/=j; break; } } if(j==t+1){ if(mp[z]==0) q.push_back(z);//判斷素數情況 break; } } ll mx=-1; for(int j=0;j<q.size();j++){//找出最大長度 dp[q[j]]++; if(mx==-1) mx=dp[q[j]]; else mx=max(mx,dp[q[j]]); } for(int j=0;j<q.size();j++){//重新賦到每一個位置 dp[q[j]]=mx; } } ll x=dp[0]; for(int i=0;i<maxn;i++){ x=max(x,dp[i]); } cout<<max((ll)1,x); }

Codeforces Round #162 (Div. 1) B. Good Sequences (dp+分解素數)