Definition: DP [I] [J] indicates the minimum number of GCD values in the previous I count.
Then there is an equation: Gg = gcd (A [I], J)
Gg = J: add this number GCD unchanged, do not add, DP [I] [J] = DP [I-1] [J]
GG! = J: t add, update answer, DP [I] [Gg] = DP [I-1] [J] + 1
The final answer is DP [N] [g] (G is the original GCD of all numbers)
Time Complexity: O (N * max (A [I])
Code:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define N 1000007int dp[703][10004];int a[704];int gcd(int a,int b){ if(!b) return a; return gcd(b,a%b);}int main(){ int n,g,i,j; scanf("%d",&n); g = 0; int maxi = 1; for(i=1;i<=n;i++) for(j=0;j<=10004;j++) dp[i][j] = Mod; for(i=1;i<=n;i++) { scanf("%d",&a[i]); g = gcd(g,a[i]); maxi = max(maxi,a[i]); dp[i][a[i]] = 1; } //printf("%d\n",g); for(i=2;i<=n;i++) { for(j=0;j<=maxi;j++) { if(dp[i-1][j] != Mod) { int gg = gcd(a[i],j); if(gg == j) dp[i][gg] = min(dp[i][gg],dp[i-1][j]); else dp[i][gg] = min(dp[i][gg],dp[i-1][j] + 1); } } } printf("%d\n",n-dp[n][g]); return 0;}
View code