设 \(b_i\) 为 \(i\) 在排列 \(p\) 中的位置。那么每次操作相当于选择一个 \(p_i\),将 \(b_{p_i}\) 增加至 \(k \in [i + 1, n]\),\(b_{p_{i + 1}}, b_{p_{i + 2}}, \ldots, b_{p_k}\) 减少 \(1\),花费 \(A\);或者将 \(b_{p_i}\) 减少至 \(k \in [1, i - 1]\),\(b_{p_{i - 1}}, b_{p_{i - 2}}, \ldots, b_{p_k}\) 增加 \(1\),花费 \(B\)。
这样看起来还不是很好做,因为一次操作的影响太大了。注意到我们只关心 \(b_i\) 的相对大小关系,\(b_i\) 具体是什么不重要,因此我们考虑改变一下操作的描述:可以将 \(b_{p_i}\) 增加或减少至任意实数 \(k \in [0, n + 1)\),花费分别为 \(A, B\)。
至此容易知道每个 \(b_i\) 最多改变一次,且我们的目标是使得 \(b\) 递增。容易设计一个 dp,\(f_{i, j}\) 为操作后 \(b_i \in [j, j + 1)\) 的花费最小值。
有转移:
- \(\forall k \in [0, j], f_{i, j} \gets f_{i - 1, k} + \begin{cases} A & b_i \le j \\ B & b_i > j \end{cases}\),表示 \(b_i\) 取 \((j, j + 1)\) 的小数。
- \(\forall k \in [0, j - 1], f_{i, j} \gets f_{i - 1, k} + \begin{cases} A & b_i < j \\ 0 & b_i = j \\ B & b_i > j \end{cases}\),表示 \(b_i\) 取整数 \(j\)。
容易维护 \(f_i\) 的前缀 \(\min\) 做到 \(O(n^2)\)。
code
// Problem: D - Rotation Sort
// Contest: AtCoder - AtCoder Grand Contest 032
// URL: https://atcoder.jp/contests/agc032/tasks/agc032_d
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 5050;
ll n, A, B, a[maxn], b[maxn], f[maxn][maxn], g[maxn][maxn];
void solve() {
scanf("%lld%lld%lld", &n, &A, &B);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
b[a[i]] = i;
}
mems(f, 0x3f);
mems(g, 0x3f);
f[0][0] = 0;
for (int i = 0; i <= n; ++i) {
g[0][i] = 0;
}
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= n; ++j) {
f[i][j] = g[i - 1][j] + (b[i] <= j ? A : B);
f[i][j] = min(f[i][j], g[i - 1][j - 1] + (b[i] < j ? A : (b[i] > j ? B : 0)));
}
g[i][0] = f[i][0];
for (int j = 1; j <= n; ++j) {
g[i][j] = min(g[i][j - 1], f[i][j]);
}
}
printf("%lld\n", g[n][n]);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
- Rotation AtCoder Contest Grand Sortrotation atcoder contest grand authentic atcoder contest grand negative atcoder contest grand atcoder contest radius grand atcoder contest grand 022 atcoder contest grand 001 histogram atcoder contest grand atcoder contest grand 019 atcoder contest grand 017 atcoder contest grand 039