CA Loves GCD (动态规划求全部子集的GCD)

博客围绕数字GCD总和问题展开,给定若干不同数字,需找出所有数字组合的GCD总和。最初考虑爆搜但因数据范围不可行,后采用01背包模型解决。介绍了状态转移方程、初始化条件,还提及离线处理gcd值、减枝降低复杂度及结果处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: http://acm.hdu.edu.cn/showproblem.php?pid=5656

问题描述
CA是一位热爱党和人民的好同志; 她也不可避免地喜欢GCD(最大的共同除数)。
现在,有ñ不同的数字。每次,CA将选择几个数字(至少一个),并找到这些数字的GCD。为了获得乐趣,CA将尝试每一个选择。在那之后,她想知道所有GCD的总和。
当且仅当选择中存在数字但在另一个数字中不存在时,我们认为这两个选择彼此不同。
输入
第一行包含 Ť 表示测试用例的数量。
Ť测试用语如下。每个测试用例在第一次包含一个整数,表示ñ,CA的数量。第二行是ñ数字。
我们保证测试中的所有数字都在[1,1000]范围内。
1 ≤ Ť≤ 50
产量
Ť 线条,每一行打印GCDs mod的总和 100000007。
样本输入
2
2
2 4
3
1 2 3
样本输出
8
10

思路

一开始拿到这道题的时候,想到的是爆搜,把所有的n的排列全部都找出来,求他们的GCD,之后累加。但是看了一眼数据范围,显然不行。

之后就开始请教题解,学到了一个新的解决方法。转载于:https://www.cnblogs.com/fenice/p/5369824.html

可以建模为01背包的模型。

  1. f[i][j]f[i][j]f[i][j]表示前i个数的任意组合中gcdgcdgcd等于jjj的组合的种类数。
  2. 转移方程有:
    1. 第i个数不取:f[i][j]+=f[i−1][j]f[i][j]+=f[i-1][j]f[i][j]+=f[i1][j]
    2. 第i个数要取:f[i][gcd(a[i],j)]+=f[i−1][j]f[i][gcd(a[i],j)]+=f[i-1][j]f[i][gcd(a[i],j)]+=f[i1][j]

可以离线处理出1000以内任意两个数的gcd值,否则会超时;
当然也可以通过减枝来降低时间复杂度(如果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值