P6786「SWTR-6」DP

题意

传送门 P6786「SWTR-6」GCDs & LCMs

题解

g c d ( b i , b j ) = d , b i = a d , b j = b d , a < b gcd(b_i,b_j)=d,b_i=ad,b_j=bd,a<b gcd(bi,bj)=d,bi=ad,bj=bd,a<b,则有
a d + b d + d = a b d ad+bd+d=abd ad+bd+d=abd a + b + 1 = a b a+b+1=ab a+b+1=ab 将式子变形得到
( a − 1 ) ( b − 1 ) = 2 (a-1)(b-1)=2 (a1)(b1)=2 得到解 a = 2 , b = 3 a=2,b=3 a=2,b=3。那么满足条件的序列按照值域排序去重后,一定满足 b i = 2 3 b i + 1 b_i=\frac{2}{3}b_{i+1} bi=32bi+1。使 a a a 有序,设 d p [ i + 1 ] dp[i+1] dp[i+1] 为以 a i a_i ai 结尾的满足条件的序列和的最大值,则有递推
d p [ i + 1 ] = max ⁡ { A [ i ] d p [ i ] + A [ i ] A [ i − 1 ] = A [ i ] d p [ k + 1 ] + A [ i ] 3 ∣ A [ i ] , 且 k 为 满 足 A [ k ] = A [ i ] / 3 ∗ 2 的 最 大 值 dp[i+1]=\max\begin{cases} A[i] & \\ dp[i]+A[i] & A[i-1]=A[i]\\ dp[k+1]+A[i] & 3\vert A[i],且k为满足A[k]=A[i]/3*2的最大值 \end{cases} dp[i+1]=maxA[i]dp[i]+A[i]dp[k+1]+A[i]A[i1]=A[i]3A[i]kA[k]=A[i]/32

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l, _ = r; i < _; ++i)
typedef long long ll;
const int maxn = 300005;
int N, A[maxn];
ll Res, dp[maxn];
unordered_map<int, int> maxId;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> N;
    rep(i, 0, N) cin >> A[i];
    sort(A, A + N);
    dp[0] = 0;
    rep(i, 0, N)
    {
        ll res = 0;
        if (i && A[i - 1] == A[i])
            res = max(res, dp[i]);
        if (A[i] % 3 == 0 && maxId.count(A[i] / 3 * 2))
            res = max(res, dp[maxId[A[i] / 3 * 2] + 1]);
        dp[i + 1] = (res += A[i]);
        Res = max(Res, res);
        maxId[A[i]] = i;
    }
    cout << Res << '\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值