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\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;
}

UESTC 923 稳住GCD DP + GCD,布布扣,bubuko.com

时间: 2024-10-18 07:16:40

UESTC 923 稳住GCD DP + GCD的相关文章

UVA10759 - Dice Throwing(dp+gcd)

UVA10759 - Dice Throwing(dp+gcd) 题目链接 题目大意:n个色子,求n个色子之和不小于x的概率. 解题思路:因为可以将题目转化成求n个色子和小于x的数目,最后再6^n减去就这个数目就是大于等于x的数目了.因为n最大就24,这样还是可以用long long来存放,最后输出要求的是分数形式,将分子分母用gcd约分一下输出即可. 代码: #include <cstdio> #include <cstring> typedef long long ll; co

HDU 5726 GCD 区间GCD=k的个数

GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2742    Accepted Submission(s): 980 Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). There ar

hdoj 2504 又见GCD 【GCD判定】

思路:一个一个的找,因为c不等于b 且b是(a, c)的最大公约数, 所以c是b的整数倍, 每找到一个c就判断与 a的最大公约数是不是b,不是的话,就继续 刚开始的时候 居然把gcd非递归形式忘了...也没想用递归形式.. 又见GCD Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10151    Accepted Submissio

D - 稳住GCD DP

http://acm.uestc.edu.cn/#/problem/show/923 给定一堆数字,求其所有数字的gcd. 现在要删除最多的数字,使得剩下的数字的gcd和原来的一样. 设dp[i][val]表示在前i个数中,得到val这个数字所需的最小数字,怎么得到val这个数字?就是gcd得到. dp[i][gcd] 然后转移就是 dp[i][a[i]] = 1是必然的,自己一个 枚举新数字得到新的gcd  val dp[i][val] = min(dp[i][val], dp[i - 1][

hdu-5656 CA Loves GCD(dp+数论)

题目链接: CA Loves GCD Time Limit: 6000/3000 MS (Java/Others)     Memory Limit: 262144/262144 K (Java/Others) Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GCD (greatest common divisor) too. Now, there are 

hdu CA Loves GCD(dp)

一道我想骂人的题,差点把我气炸了. 题意: 求一个数的集合中(非多重集,每个数只出现一次)所有子集的gcd的和.结果MOD10^8+7输出. 输入输出不说了,自己看吧,不想写了. 当时我真把它当作数论题来写了,以为可以推导出什么公式然后化简大量重复的操作的.结果最后也没找到.最后题解说是dp,我同学说是暴力,吐血10升. 然后弄出来dp方程之后还是反复的wa,方程明明没啥问题,愣是卡了2个小时找不出错误,心情烦躁的要命,坑爹的室友还各种看视频打游戏,还不带耳机,我自己只好带着耳机大声放音乐,最后

hdu 5656 CA Loves GCD dp

CA Loves GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GCD (greatest common divisor) too. Now, there are N diffe

cf842C 树形dp+gcd函数

树形dp用一下就好了 /* dp[i]表示不删节点的gcd值 每个结点开个vector用来存储删一个点之后的最大值 然后排序 去重 */ #include<bits/stdc++.h> #include<vector> using namespace std; #define maxn 200005 struct Edeg{int to,nxt;}edge[maxn<<1]; int n,a[maxn],head[maxn],tot,dp[maxn]; vector&l

Array GCD CodeForces - 624D (dp,gcd)

大意: 给定序列, 给定常数a,b, 两种操作, (1)任选一个长为$t$的子区间删除(不能全部删除), 花费t*a. (2)任选$t$个元素+1/-1, 花费t*b. 求使整个序列gcd>1的最少花费. 题目有个限制是不能全部删除, 所以最后一定剩余a[1]或a[n], 暴力枚举a[1]与a[n]的所有素因子即可. 这场div. 2题目感觉都挺简单的, 但实现起来各种出错...........各种细节还是没考虑好...... #include <iostream> #include &