📜  给定GCD的最小子阵列(1)

📅  最后修改于: 2023-12-03 15:41:16.158000             🧑  作者: Mango

给定GCD的最小子阵列

问题描述

给定一个长度为 $n$ 的整数序列 $a_1,a_2,\dots ,a_n$,求所有子数组中 GCD(最大公约数)为 $g$ 的子数组中最短的长度是多少?

解决方案

设 $dp[i][j]$ 表示以 $a_i$ 结尾且 gcd 为 $j$ 的最短长度。

如果 $j\mid a_i$,则 $dp[i][j]=1$,否则 $dp[i][j]=dp[i-1][\gcd(j,a_i)]+1$。

因此,最终答案为 $\min\limits_{i=1}^n{dp[i][g]}$。

时间复杂度为 $O(n^2\log \max\limits_{i=1}^n a_i)$。

代码实现
int dp[MAXN][MAXN], a[MAXN];

int solve(int n, int g) {
    memset(dp, 0x3f, sizeof(dp));
    for (int i = 1; i <= n; ++i) {
        dp[i][a[i]] = 1;
        for (int j = 1; j <= MAXN; ++j)
            if (dp[i - 1][j] < INF)
                dp[i][__gcd(j, a[i])] = min(dp[i][__gcd(j, a[i])], dp[i - 1][j] + 1);
    }
    int ans = INF;
    for (int i = 1; i <= n; ++i) ans = min(ans, dp[i][g]);
    return ans == INF ? -1 : ans;
}
参考链接
  1. 【DP】给定 GCD 的最小子阵列(lei150e)