zoukankan      html  css  js  c++  java
  • UESTC 923 稳住GCD DP + GCD

    定义:dp[i][j] 表示 在前i个数中,使整个gcd值为j时最少取的数个数。

    则有方程: gg = gcd(a[i],j) 

    gg == j : 添加这个数gcd不变,不添加,  dp[i][j] = dp[i-1][j]

    gg != j: t添加,更新答案,                dp[i][gg] = dp[i-1][j] + 1

    最后答案为dp[n][g] (g为原始的所有数的gcd)

    时间复杂度: O(n*max(a[i]))

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 1000007
    
    int 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
    ",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-dp[n][g]);
        return 0;
    }
    View Code
  • 相关阅读:
    养生之《爱的供养》
    道家养生,与佛家养德
    个人的佛法·5·活着,与死去
    自我囚禁与安住于轮回
    个人的佛法·4·我是不是东西?
    个人的佛法·2
    我们都是生命的灯塔
    大O表示法是什么?
    uni-app商城项目(01)
    2059
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3813537.html
Copyright © 2011-2022 走看看