【2024年浙江工商大学程序设计竞赛新生赛(同步赛)部分题解】

比赛链接

C. 交换

题目大意

给定一个长度为 n n n 的数组 a a a。一开始你有一个总和 s = 0 s = 0 s=0

现在你需要做 n n n 次操作,第 i i i 次操作的流程如下( 1 ⩽ i ⩽ n 1 \leqslant i \leqslant n 1in):

  • 选择一个下标 p ∈ [ 1 , n ) p \in [1, n) p[1,n),然后交换 a [ p ] ,   a [ p + 1 ] a[p], \ a[p + 1] a[p], a[p+1](如果你不想选,这一小步可以跳过);
  • s : = s + a [ i ] s := s + a[i] s:=s+a[i]

n n n 次操作结束后你能获得的最大的 s s s

数据范围

  • 2 ⩽ n ⩽ 500 2 \leqslant n \leqslant 500 2n500
  • 1 ⩽ a i ⩽ 1 0 6 1 \leqslant a_i \leqslant 10^6 1ai106

Solution

我们观察这个数据范围,一眼 O ( n 3 ) O(n^3) O(n3) 的解法,而且大概率 d p dp dp。只不过有可能是 O ( n 2 ) O(n^2) O(n2) 的状态, O ( n ) O(n) O(n) 的转移;还有可能是 O ( n 3 ) O(n^3) O(n3) 的状态,以及需要优化成 O ( 1 ) O(1) O(1) 的转移。

首先,我们的状态需要操作次数 i i i,因为每个操作次数要加的 a [ i ] a[i] a[i] 不一样。其次,我们还要交换次数 j j j,因为每次操作可以不选下标 p p p 进行交换。最后,我们还要知道交换后 a [ i ] a[i] a[i] 变成了什么,即 a [ i ] : = a [ k ] a[i] := a[k] a[i]:=a[k],我们仅需记录这个 k k k

这样就确定了我们的状态是 O ( n 3 ) O(n^3) O(n3) 的,因此我们一定需要 O ( 1 ) O(1) O(1) 的优化转移。

d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 表示进行了 i i i 次操作,已经做了 j j j 次交换,将 a [ i ] : = a [ k ] a[i] := a[k] a[i]:=a[k] 能得到的最大 s s s

状态转移:

  • d p [ i ] [ j ] [ k ] = d p [ i − 1 ] [ j − 1 ] [ k ] + a [ k ] dp[i][j][k] = dp[i - 1][j - 1][k] + a[k] dp[i][j][k]=dp[i1][j1][k]+a[k],表示第 i i i 次操作要交换 a [ i − 1 ] a[i - 1] a[i1] a [ i ] a[i] a[i],而 a [ i − 1 ] a[i - 1] a[i1] 在上一次操作中已经有 a [ i − 1 ] : = a [ k ] a[i - 1] := a[k] a[i1]:=a[k]
  • d p [ i ] [ j ] [ k ] = d p [ i − 1 ] [ j − ∣ i − k ∣ ] [ k 1 ] + a [ k ] ,   k 1 < k dp[i][j][k] = dp[i - 1][j - |i - k|][k_1] + a[k], \ k_1 < k dp[i][j][k]=dp[i1][jik][k1]+a[k], k1<k
    • 满足的条件有 j − ∣ i − k ∣ ⩾ 0 j - |i - k| \geqslant 0 jik0,即 max ⁡ ( 0 ,   i − j ) ⩽ k ⩽ min ⁡ ( n ,   i + j ) \max(0, \ i - j) \leqslant k \leqslant \min(n, \ i + j) max(0, ij)kmin(n, i+j)
    • ∣ i − k ∣ |i - k| ik 表示把 a [ k ] a[k] a[k] 挪到 a [ i ] a[i] a[i] 需要 ∣ i − k ∣ |i - k| ik 交换;
    • 除此之外, k 1 < k k_1 < k k1<k 表示第 i − 1 i - 1 i1 次操作可以交换到 a [ i − 1 ] a[i - 1] a[i1] 的为 a [ k 1 ] a[k_1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值