前言
大佬的题解
笔记
理解为动态规划
前提(i, j
a, j > i)(dp[i] 为以i结尾的最大长度)
对于每个i --> j, 方程为 dp[j] = max(dp[j], dp[i] + 1)
每个j 的最大长度只与 i 的最大长度有关
80分代码
没有进行因子分解的
优化,直接枚举导致超时
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int t, n, mx; const int N = 1e5 + 5; int a[N], dp[N], ans; int main() { scanf("%d", &t); while(t--) { ans = 1; scanf("%d", &n); memset(a, 0, sizeof(a)); memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { int x; scanf("%d", &x); a[x] = 1; mx = max(mx, x); } for(int i = 1; i <= mx; i++) { if(a[i]) dp[i] = max(dp[i], 1); else continue; int temp = i; for(int z = 2; z <= temp; z++) { if(temp % z == 0)// 找到质因子 开始i->j 的转移 { for(int j = i + z; j <= mx; j += z) { if(a[j]){dp[j] = max(dp[j], dp[i] + 1);ans = max(dp[j], ans); break;} } } else continue; while(temp % z == 0) temp /= z; } } cout << ans << endl; } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int t, n, mx; const int N = 1e5 + 5; int a[N], dp[N], ans; int main() { scanf("%d", &t); while(t--) { ans = 1; scanf("%d", &n); memset(a, 0, sizeof(a)); memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { int x; scanf("%d", &x); a[x] = 1; mx = max(mx, x); } //对于每个优秀的i -> j 转移 条件是 j是i中每个质因子的最小倍数 //状态转移方程 (dp[j] = max dp[i] + 1) // 1.枚举i 找质因子 // 2. 找到j转移 for(int i = 1; i <= mx; i++) { if(a[i]) dp[i] = max(dp[i], 1); else continue; int temp = i; for(int z = 2; z * z <= temp; z++) { if(temp % z == 0)// 找到质因子 开始i->j 的转移 { for(int j = i + z; j <= mx; j += z) { if(a[j]){dp[j] = max(dp[j], dp[i] + 1);ans = max(dp[j], ans); break;} } } else continue; while(temp % z == 0) temp /= z; } if(temp > 1))//剩下了个大于根号的质数 { for(int j = i + temp; j <= mx; j += temp) { if(a[j]){dp[j] = max(dp[j], dp[i] + 1);ans = max(dp[j], ans); break;} } } } cout << ans << endl; } return 0; }