Divan and Kostomuksha (easy version) dp,gcd(2100)
生活随笔
收集整理的这篇文章主要介绍了
Divan and Kostomuksha (easy version) dp,gcd(2100)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
题意 :
- 对于给定序列,任意打乱顺序,问 :∑i=1ngcd(a1,a2,...,an)\sum_{i=1}^{n}gcd(a_1,a_2,...,a_n)i=1∑ngcd(a1,a2,...,an)的最大值是多少
思路 :
- 序列的gcd一定是递减的
- 设cnt(i)cnt(i)cnt(i)表示以i为因数(包含i)的数字的数量,dp[i]dp[i]dp[i]表示将i放在第一个的答案
- 转移方程为dp[j]=max(dp[j],dp[i]+cnt(j)∗(j−i)+dp[i])dp[j] = max(dp[j], dp[i] + cnt(j) * (j - i) + dp[i])dp[j]=max(dp[j],dp[i]+cnt(j)∗(j−i)+dp[i])
- 这个方程的意义是,选择cnt(j)cnt(j)cnt(j)个数字放在最前面,那么产生的gcd贡献是cnt(j)∗jcnt(j)*jcnt(j)∗j
- 那么对于后一段填不了j倍数的位置,不能产生j的贡献
- 后一段的贡献怎么算呢?可以枚举j的因数(不包含j)(因为后面的数如果不是j的因数,同时也不是j的倍数,产生的贡献为1,这等价于填1,而1也是j的因数 <- 这是一个关键的思路,删繁就简)
- 对于j的因数i(i!=j),因为dp[i]dp[i]dp[i]算的是整个序列的答案,那么后一段也包含进去了,但是前一段会有重复计算,产生贡献为i∗cnt[j]i*cnt[j]i∗cnt[j](gcd为i,一共cnt(j)cnt(j)cnt(j)个数字),要减去这个贡献
总结
以上是生活随笔为你收集整理的Divan and Kostomuksha (easy version) dp,gcd(2100)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 王道计算机考研 数据结构 (栈和队列)
- 下一篇: Divan and Kostomuksh