多重背包问题

多重背包问题

状态表示: f [ i ] [ j ] f[i][j] f[i][j]: 在前 i i i 个数中选, 每个物品不超过 s i s_i si 个体积总和不超过 j j j 的集合
状态属性: 总价值的最大值
状态计算
1.第 i i i个物品选 0 0 0
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − 0 ∗ v [ i ] ] + 0 ∗ w [ i ] ) ; f[i][j]= max(f[i][j], f[i - 1][j - 0 * v[i]] + 0 * w[i]); f[i][j]=max(f[i][j],f[i1][j0v[i]]+0w[i]);
2.第 i i i 个物品选 1 1 1
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − 1 ∗ v [ i ] ] + 1 ∗ w [ i ] ) f[i][j] = max(f[i][j], f[i - 1][j - 1 * v[i]] + 1 * w[i]) f[i][j]=max(f[i][j],f[i1][j1v[i]]+1w[i]);
3.第 i i i 个物品选 2 2 2
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − 3 ∗ v [ i ] ] + 2 ∗ w [ i ] ) ; f[i][j] = max(f[i][j], f[i - 1][j - 3 * v[i]] + 2 * w[i]); f[i][j]=max(f[i][j],f[i1][j3v[i]]+2w[i]);
4.第 i i i 个物品选 3 3 3
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − 4 ∗ v [ i ] ] + 4 ∗ w [ i ] ) ; f[i][j] = max(f[i][j], f[i - 1][j - 4 * v[i]] + 4 * w[i]); f[i][j]=max(f[i][j],f[i1][j4v[i]]+4w[i]);
. . . ... ...

第i个物品选 s s s f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − s [ i ] ∗ v [ i ] ] + s [ i ] ∗ w [ i ] ) ; f[i][j] = max(f[i][j], f[i - 1][j - s[i] * v[i]] + s[i] * w[i]); f[i][j]=max(f[i][j],f[i1][js[i]v[i]]+s[i]w[i]);

1.朴素做法 时间复杂度 O(n × m × s)

for(int i = 1; i <= n; i ++ )
    for(int j = 0; j <= m; j ++ )
    for(int k = 0; k <= s[i] && j >= k * v[i]; k ++ )
        f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);

2.一些奇奇怪怪的做法 时间复杂度: 比朴素做法还慢
s i s_i si 个物品拆分成一个个物品 当做 01 01 01 背包来做

int cnt = n;
    for(int i = 1; i <= n; i ++ )
    {
        cin >> v[i] >> w[i] >> s[i];
        for(int j = 1; j < s[i]; j ++ )
        v[ ++ cnt] = v[i], w[cnt] = w[i];
    }   
    for(int i = 1; i <= cnt; i ++ )
    for(int j = 0; j <= m; j ++ )
    {
    f[i][j] = f[i - 1][j];
    if(j >= v[i])
        f[i][j] = max(f[i][j], f[i - 1][j - v[i]] +  w[i]);
    }

3.二进制优化 时间复杂度 O( n 2 l o g s n^2logs n2logs)
如果直接遍历转化为 01 01 01 背包问题,是每次都拿一个来问,取了好还是不取好。那么根据数据范围,这样的时间复杂度是O( n 3 n^3 n3),这个时间复杂度很不理想,我们肯定想去优化它,我们不难知道任何一个整数都能用一个二进制数来表示,所以我们可以将s个物品拆分成多个二进制数, 如 9 = 2 0 + 2 3 9 = 2^0 + 2^3 9=20+23, 9 9 9 个物品可以拆分为体积为 8 v 8v 8v,价值为 8 w 8w 8w 的物品和体积为 v v v,价值为 w w w 的物品,这样可以大大降低时间复杂度

for(int i = 1; i <= n; i ++ )
    {
        int V, W, S;
        cin >> V >> W >> S;
        int k = 1;
        while(k <= S)
        {
            v[++ cnt] = k * V;
            w[cnt] = k * W;
            S -= k;
            k  <<= 1;
        }
        if(S > 0 ) v[++ cnt] = S * V, w[cnt] = S * W;
    }
    n = cnt;
    for(int i = 1; i <= n; i ++ )
    for(int j = 0; j <= m; j ++ )
    {
            f[i][j] = f[i - 1][j];
            if(j >= v[i])
            f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
    }

代码看起来很合理,时间复杂度也很满意,但是当你提交时会发现SE了, 为啥? 答案是f数组开两维需要的空间很大,容易爆内存,所以我们需要进行空间优化

3.空间优化
通过完全背包和 01 01 01 背包的空间优化,我们肯定也想对多重背包进行空间优化
01 01 01背包 f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − v [ i ] ] + w [ i ] ) ; f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); f[i][j]=max(f[i][j],f[i1][jv[i]]+w[i]);
完全背包 f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − v [ i ] ] + w [ i ] ) ; f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); f[i][j]=max(f[i][j],f[i1][jv[i]]+w[i]);
我们会发现惊人的相似,不,就是完全一样,那我们自然可以想到从大到小枚举体积,然后将空间压缩为一维

for(int i = 1; i <= n; i ++ )
    {
        int V, W, S;
        cin >> V >> W >> S;
        int k = 1;
        while(k <= S)
        {
            v[++ cnt] = k * V;
            w[cnt] = k * W;
            S -= k;
            k  <<= 1;
        }
        if(S > 0 ) v[++ cnt] = S * V, w[cnt] = S * W;
    }
    n = cnt;
    for(int i = 1; i <= n; i ++ )
    for(int j = m; j >= v[i]; j -- )
    f[j] = max(f[j], f[j - v[i]] + w[i]);

但是我们这时候会想,为啥我们不能像完全背包哪一样优化呢,我们可以试着模仿完全背包做一下
在这里插入图片描述

我们会发现下面比上面多了一项,但是完全背包为啥项数是相同的呢? 因为完全背包是可以取无穷次的,所以项数一定是相同的,因为多重背包上下项数不同,所以我们不能进行优化

4.进行了上述的空间时间优化后,我们还是不够满意 我们尝试能不能将时间复杂度降低到O( N × V N × V N×V) 呢? 答案是可以的,那要怎么优化呢? 我们将会用到一个数据结构, 叫单调队列

f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v ] + w , ⋯ , f [ i − 1 ] [ j − s ∗ v ] + s ∗ w ) ; f[i][j] = max(f[i − 1][j],f[i − 1][j − v] + w,⋯,f[i − 1][j − s * v] + s * w); f[i][j]=max(f[i1][j],f[i1][jv]+w,,f[i1][jsv]+sw);
f [ i ] [ j − v ] = m a x ( f [ i − 1 ] [ j − v ] , . . . f [ i − 1 ] [ j − ( s + 1 ) ∗ v ] + s ∗ w ) ; f[i][j − v] = max( f[i − 1][j − v], ... f[i − 1][j − (s + 1) * v] + s * w); f[i][jv]=max(f[i1][jv],...f[i1][j(s+1)v]+sw);
f [ i ] [ j − 2 ∗ v ] = m a x ( f [ i − 1 ] [ j − 2 ∗ v ] , f [ i − 1 ] [ j − 3 ∗ v ] + w , ⋯ , f [ i − 1 ] [ j − ( s + 2 ) ∗ v ) + s ∗ w ] f[i][j− 2 * v] = max(f[i − 1][j − 2 * v], f[i − 1][j − 3 * v] + w,⋯,f[i − 1][j − (s + 2) * v) + s * w] f[i][j2v]=max(f[i1][j2v],f[i1][j3v]+w,,f[i1][j(s+2)v)+sw]
. . . ... ...
f [ i ] [ r + s ∗ v ] = m a x ( f [ i − 1 ] [ r + s ∗ v ] , f [ i − 1 ] [ r + ( s − 1 ) ∗ v ) ] + w , . . . , f [ i − 1 ] [ r ] ) + s w ) ; f[i][r + s * v]= max(f[i − 1][r + s * v],f[i − 1][r + (s − 1) * v)] + w,...,f[i − 1][r])+sw); f[i][r+sv]=max(f[i1][r+sv],f[i1][r+(s1)v)]+w,...,f[i1][r])+sw);
f [ i ] [ r + ( s − 1 ) ∗ v ] = m a x ( f [ i − 1 ] [ r + ( s − 1 ) ∗ v ] , . . . , f [ i − 1 ] [ r ] + ( s − 1 ) ∗ w ) f[i][r + (s − 1) * v] = max(f[i−1][r + (s − 1) * v],...,f[i − 1][r]+ (s − 1) * w) f[i][r+(s1)v]=max(f[i1][r+(s1)v],...,f[i1][r]+(s1)w)
f [ i ] [ r + 2 ∗ v ] = m a x ( f [ i − 1 ] [ r + 2 ∗ v ] , f [ i − 1 ] [ r + v ] + w , f [ i − 1 ] [ r ] ) + 2 ∗ w ) f[i][r + 2 * v] = max(f[i − 1][r + 2 * v],f[i − 1][r + v] + w, f[i − 1][r]) + 2 * w) f[i][r+2v]=max(f[i1][r+2v],f[i1][r+v]+w,f[i1][r])+2w)
f [ i ] [ r + v ] = m a x ( f [ i − 1 ] [ r + v ] , f [ i − 1 ] [ r ] + w ) f[i][r + v] = max(f[i − 1][r + v],f[i − 1][r] + w) f[i][r+v]=max(f[i1][r+v],f[i1][r]+w)
f [ i ] [ r ] = f [ i − 1 ] [ r ] f[i][r] = f[i − 1][r] f[i][r]=f[i1][r]

为了更好的阅读体验我们可以先把 i i i 去掉
f [ j ] = m a x ( f [ j ] , f [ j − v ] + w , ⋯ , f [ j − s ∗ v ] + s ∗ w ) ; f[j] = max(f[j],f[j − v] + w,⋯,f[j − s * v] + s * w); f[j]=max(f[j],f[jv]+w,,f[jsv]+sw);
f [ j − v ] = m a x ( f [ j − v ] , . . . f [ j − ( s + 1 ) ∗ v ] + s ∗ w ) ; f[j − v] = max( f[j − v], ... f[j − (s + 1) * v] + s * w); f[jv]=max(f[jv],...f[j(s+1)v]+sw);
f [ j − 2 ∗ v ] = m a x ( f [ j − 2 ∗ v ] , f [ j − 3 ∗ v ] + w , ⋯ , f [ j − ( s + 2 ) ∗ v ) + s ∗ w ] f[j− 2 * v] = max(f[j − 2 * v], f[j − 3 * v] + w,⋯,f[j − (s + 2) * v) + s * w] f[j2v]=max(f[j2v],f[j3v]+w,,f[j(s+2)v)+sw]
. . . ... ...
f [ r + s ∗ v ] = m a x ( f [ r + s ∗ v ] , f [ r + ( s − 1 ) ∗ v ) ] + w , . . . , f [ r ] ) + s w ) ; f[r + s * v]= max(f[r + s * v],f[r + (s − 1) * v)] + w,...,f[r])+sw); f[r+sv]=max(f[r+sv],f[r+(s1)v)]+w,...,f[r])+sw);
f [ r + ( s − 1 ) ∗ v ] = m a x ( f [ r + ( s − 1 ) ∗ v ] , . . . , f [ r ] + ( s − 1 ) ∗ w ) f[r + (s − 1) * v] = max(f[r + (s − 1) * v],...,f[r]+ (s − 1) * w) f[r+(s1)v]=max(f[r+(s1)v],...,f[r]+(s1)w)
f [ r + 2 ∗ v ] = m a x ( f [ r + 2 ∗ v ] , f [ r + v ] + w , f [ r ] ) + 2 ∗ w ) f[r + 2 * v] = max(f[r + 2 * v],f[r + v] + w, f[r]) + 2 * w) f[r+2v]=max(f[r+2v],f[r+v]+w,f[r])+2w)
f [ r + v ] = m a x ( f [ r + v ] , f [ r ] + w ) f[r + v] = max(f[r + v],f[r] + w) f[r+v]=max(f[r+v],f[r]+w)
f [ r ] = f [ r ] f[r] = f[r] f[r]=f[r]
看到这里你可能会疑惑了, 这是啥啊, 我咋看不懂, r是啥,为啥前面是减去v,后面咋又加上 v v v
在这里, r r r 是指的 j j j 除以 v v v 后的余数,因为用一个物品会消耗v,用s个物品会消耗 s × v s × v s×v 的体积, 最后会剩余一部分体积,即 j j % v j, 所以 f [ i ] [ j − v ] f[i][j - v] f[i][jv] 最后就会变成 f [ i ] [ r ] f[i][r] f[i][r]
然后往回倒退,每次就是加上 v v v

然后再把这个递推式倒过来观察
f [ i ] [ r ] = f [ i − 1 ] [ r ] f[i][r] = f[i − 1][r] f[i][r]=f[i1][r]
f [ i ] [ r + v ] = m a x ( f [ i − 1 ] [ r + v ] , f [ i − 1 ] [ r ] + w ) f[i][r + v] = max(f[i − 1][r + v],f[i − 1][r] + w) f[i][r+v]=max(f[i1][r+v],f[i1][r]+w)
f [ i ] [ r + 2 ∗ v ] = m a x ( f [ i − 1 ] [ r + 2 ∗ v ] , f [ i − 1 ] [ r + v ] + w , f [ i − 1 ] [ r ] ) + 2 ∗ w ) f[i][r + 2 * v] = max(f[i − 1][r + 2 * v],f[i − 1][r + v] + w, f[i − 1][r]) + 2 * w) f[i][r+2v]=max(f[i1][r+2v],f[i1][r+v]+w,f[i1][r])+2w)
. . . ... ...

f [ i ] [ r + ( s − 1 ) ∗ v ] = m a x ( f [ i − 1 ] [ r + ( s − 1 ) ∗ v ] , . . . , f [ i − 1 ] [ r ] + ( s − 1 ) ∗ w ) f[i][r + (s − 1) * v] = max(f[i − 1][r + (s − 1) * v],...,f[i − 1][r] + (s − 1) * w) f[i][r+(s1)v]=max(f[i1][r+(s1)v],...,f[i1][r]+(s1)w)
f [ i ] [ r + s ∗ v ] = m a x ( f [ i − 1 ] [ r + s ∗ v ] , f [ i − 1 ] [ r + ( s − 1 ) ∗ v ) ] + w , . . . , f [ i − 1 ] [ r ] ) + s ∗ w ) ; f[i][r + s * v] = max( f[i − 1][r + s * v],f[i − 1][r + (s − 1) * v)] + w,...,f[i − 1][r]) + s * w); f[i][r+sv]=max(f[i1][r+sv],f[i1][r+(s1)v)]+w,...,f[i1][r])+sw); 滑动窗口已满
f [ i ] [ r + ( s + 1 ) ∗ v ] = m a x ( f [ i − 1 ] [ r + ( s + 1 ) ∗ v ] , f [ i − 1 ] [ r + s ∗ v ] + w , ⋯ , f [ i − 1 ] [ r + v ] + s ∗ w ) ; f[i][r + (s + 1) * v] = max(f[i - 1][r + (s + 1) * v], f[i - 1][r + s * v] + w,⋯,f[i - 1][r + v]+ s * w); f[i][r+(s+1)v]=max(f[i1][r+(s+1)v],f[i1][r+sv]+w,,f[i1][r+v]+sw); 滑动窗口已满

. . . ... ...

f [ i ] [ j − 2 ∗ v ] = m a x ( f [ i − 1 ] [ j − 2 ∗ v ] , f [ i − 1 ] [ j − 3 ∗ v ] + w , ⋯ , f [ i − 1 ] [ j − ( s + 2 ) ∗ v ) + s ∗ w ] ; f[i][j− 2 * v] = max(f[i − 1][j − 2 * v], f[i − 1][j − 3 * v] + w,⋯,f[i − 1][j − (s + 2) * v) + s * w]; f[i][j2v]=max(f[i1][j2v],f[i1][j3v]+w,,f[i1][j(s+2)v)+sw]; 滑动窗口已满
f [ i ] [ j − v ] = m a x ( f [ i − 1 ] [ j − v ] , . . . f [ i − 1 ] [ j − ( s + 1 ) ∗ v ] + s ∗ w ) ; f[i][j − v] = max(f[i − 1][j − v], ... f[i − 1][j − (s + 1) * v] + s * w); f[i][jv]=max(f[i1][jv],...f[i1][j(s+1)v]+sw); 滑动窗口已满
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v ] + w , ⋯ , f [ i − 1 ] [ j − s ∗ v ] + s ∗ w ) ; f[i][j] = max(f[i − 1][j],f[i − 1][j − v] + w,⋯,f[i − 1][j − s * v] + s * w); f[i][j]=max(f[i1][j],f[i1][jv]+w,,f[i1][jsv]+sw); 滑动窗口已满

或许你还没有看懂,那么你可以看这里

f r f_r fr
f r + 2 v , f r + v , f r f_{r + 2v},f_{r + v}, f_r fr+2v,fr+v,fr
f r + ( s − 1 ) v , f r + ( s − 2 ) v , . . . f r + 2 v , f r + v , f r f_{r + (s - 1)v}, f_{r + (s - 2)v}, ... f_{r + 2v}, f_{r + v}, f_r fr+(s1)v,fr+(s2)v,...fr+2v,fr+v,fr
f r + s v , f r + ( s − 1 ) v , . . . f r + 2 v , f r + v , f r f_{r + sv}, f_{r + (s - 1)v}, ... f_{r + 2v}, f_{r + v}, f_r fr+sv,fr+(s1)v,...fr+2v,fr+v,fr

. . . ... ...

f j − 2 v , f j − 3 v , f j − 4 v , . . . f j − ( s + 2 ) v f_{j - 2v}, f_{j - 3v}, f_{j - 4v}, ... f_{j - (s + 2)v} fj2v,fj3v,fj4v,...fj(s+2)v
f j − v , f j − 2 v , f j − 3 v , . . . f j − ( s + 1 ) v f_{j - v}, f_{j - 2v}, f_{j - 3v}, ... f_{j - (s + 1)v} fjv,fj2v,fj3v,...fj(s+1)v
f j , f j − v , f j − 2 v , . . . f j − s v f_j, f_{j - v}, f_{j - 2v},... f_{j - sv} fj,fjv,fj2v,...fjsv

这里差不多就能看出规律了,然后我们再把 w w w 加上去,

f r f_r fr
f r + 2 v , f r + v + w , f r + 2 w f_{r + 2v}, f_{r + v} + w, f_r + 2w fr+2v,fr+v+w,fr+2w
f r + ( s − 1 ) v , f r + ( s − 2 ) v + w , . . . f r + 2 v + ( s − 3 ) w , f r + v + ( s − 2 ) w , f r + ( s − 1 ) w f_{r + (s - 1)v}, f_{r + (s - 2)v} + w, ... f_{r + 2v} + (s - 3)w, f_{r + v} + (s - 2)w, f_r + (s - 1)w fr+(s1)v,fr+(s2)v+w,...fr+2v+(s3)w,fr+v+(s2)w,fr+(s1)w
f r + s v , f r + ( s − 1 ) v + w , . . . f r + 2 v + ( s − 2 ) w , f r + v + ( s − 1 ) w , f r + s w f_{r + sv}, f_{r + (s - 1)v} + w, ... f_{r + 2v} + (s - 2)w, f_{r + v} + (s - 1)w, f_r + sw fr+sv,fr+(s1)v+w,...fr+2v+(s2)w,fr+v+(s1)w,fr+sw

然后我们要将 v , w v,w v,w 建立起关系,我们提取 w w w

f r f_r fr
f r + 2 v − 2 w , f r + v − w , f r f_{r + 2v} - 2w, f_{r + v} -w, f_r fr+2v2w,fr+vw,fr
f r + ( s − 1 ) v − ( s − 1 ) w , f r + ( s − 2 ) v + ( s − 2 ) w , . . . f r + 2 v − 2 w , f r + v − w , f r f_{r + (s - 1)v} - (s - 1)w, f_{r + (s - 2)v} + (s - 2)w, ... f_{r + 2v} - 2w, f_{r + v} - w, f_r fr+(s1)v(s1)w,fr+(s2)v+(s2)w,...fr+2v2w,fr+vw,fr
f r + s v − s w , f r + ( s − 1 ) v − ( s − 1 ) w , . . . f r + 2 v − 2 w , f r + v − w , f r f_{r + sv} - sw, f_{r + (s - 1)v} - (s - 1)w, ... f_{r + 2v} - 2w, f_{r + v} - w, f_r fr+svsw,fr+(s1)v(s1)w,...fr+2v2w,fr+vw,fr

可以发现每个序列的长度不超过 s + 1 s+1 s+1,因为最多可以选 s s s个,然后不选也是一种情况,共 s + 1 s + 1 s+1 种情况
于是通过该 滑动窗口 ,我们就能在 线性 的时间里求出 i 阶段里,所有满足 j = r j = r % v j=r f [ i ] [ j ] f[i][j] f[i][j] 滑动窗口
求 最大值 的实现,只需利用 队列 在队头维护一个 最大值 的 单调递减 的 单调队列 即可
为了更新所有 i i i 阶段里的状态 f [ i ] [ j ] f[i][j] f[i][j],我们只需再额外枚举所有的 余数 r 即可
时间复杂度:O( n × v n × v n×v )
空间复杂度:O( n × v n × v n×v)
滑动窗口的长度为 s + 1 s+1 s+1

 for(int i = 0; i < n; i ++ )
     {
        memcpy(pre,f,sizeof f);   //把上一层计算的状态复制过来
        int v,s,w;  //体积 次数 价值
        v = read(), w = read(), s = read();
        for(int j = 0; j < v; j ++ )  //枚举每一个余数 0~v-1
        //枚举 %v 的余数 因为例如 当v = 3 ,f[0],f[1],f[2]是不同的集合 
        //当s = 3  f[12] 可以由 f[9],f[6],f[3] 转化而来 所以%v 余数相同的 f[j] 可以划分在同一个集合 
        {
           int hh = 0, tt = -1;
           for(int k = j; k <= m; k += v)    
           //因为j是 %v的余数  所以枚举 还原j, %v 就相当于减去了n 个 v  我们在不超过容积m的前提下,持续递增k
           {
             //利用单调队列
            //1.超出滑动窗口的 弹出队列
            if(hh <= tt && q[hh] < k - s * v)  ++hh;
                //当队列不空  当 滑动窗口的队头 离开了窗口,则将队头出队,
                //因为s为最大数量,所以滑动窗口的最大长度为s 从当前位置k开始 往前推s个位置 
                //如果队头处于k-s*v之前 则队头离开了滑动窗口,将其出队
            while(hh <= tt && pre[q[tt]] - (q[tt] - j) / v * w <= pre[k] - (k - j) / v * w ) tt--;
              //当队列不空  为保持滑动窗口的单调递减   滑动窗口的尾值必须大于新入队的元素 否则将队尾出队
              //队尾元素是 pre[j + k * v] - k * w,  q[tt] == j + k * v  - > (q[tt] - j )/v == k 
              if(hh <= tt )     f[k] = max(f[k],pre[q[hh]] + (k - q[hh]) / v * w);
                //更新时 用 队头元素 + 中间间隔了多少个w  即k*w 来更新
                //当队列不空时更新f   f数组储存的是滑动窗口的最大值  
                //将新元素入队  
              q[++tt] = k;
           } 
        }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广西小蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值