E - Sorted and Sorted
Time limit : 2sec / Memory limit : 1024MB
Score : 600 points
Problem Statement
There are
2N
2
N
balls,
N
N
white and black, arranged in a row. The integers from
1
1
through are written on the white balls, one on each ball, and they are also written on the black balls, one on each ball. The integer written on the
i
i
-th ball from the left () is
ai
a
i
, and the color of this ball is represented by a letter
ci
c
i
.
ci=
c
i
=
W
represents the ball is white;
ci=
c
i
=
B
represents the ball is black.
Takahashi the human wants to achieve the following objective:
- For every pair of integers (i,j) ( i , j ) such that 1≤i<j≤N 1 ≤ i < j ≤ N , the white ball with i i written on it is to the left of the white ball with written on it.
- For every pair of integers (i,j) ( i , j ) such that 1≤i<j≤N 1 ≤ i < j ≤ N , the black ball with i i written on it is to the left of the black ball with written on it.
In order to achieve this, he can perform the following operation:
- Swap two adjacent balls.
Find the minimum number of operations required to achieve the objective.
Constraints
1≤N≤2000
1
≤
N
≤
2000
1≤ai≤N
1
≤
a
i
≤
N
ci=
c
i
=
W
or
ci=
c
i
=
B
.
If
i≠j
i
≠
j
,
(ai,ci)≠(aj,cj)
(
a
i
,
c
i
)
≠
(
a
j
,
c
j
)
.
Input
Input is given from Standard Input in the following format:
N N
a1 a 1
c2 c 2 a2 a 2
: :
a2N a 2 N
Output
Print the minimum number of operations required to achieve the objective.
Samples
Input | Output |
---|---|
3 B 1 W 2 B 3 W 1 W 3 B 2 | 4 |
4 B 4 W 4 B 3 W 3 B 2 W 2 B 1 W 1 | 18 |
9 W 3 B 1 B 4 W 1 B 5 W 9 W 2 B 6 W 5 B 3 W 8 B 9 W 7 B 2 B 8 W 4 W 6 B 7 | 41 |
Sample 1:
The objective can be achieved in four operations, for example, as follows:
Swap the black 3 and white 1.
Swap the white 1 and white 2.
Swap the black 3 and white 3.
Swap the black 3 and black 2.
解题思路
先看一个最基本的问题:
已知 1 1 到 的一个排列,每次操作可以交换相邻两数,求至少多少次操作才能将这个数列变为 1,2,3,⋯,N 1 , 2 , 3 , ⋯ , N
答案就是原数列的逆序对对数。证明如下:
目标数列显然满足这样一个性质:对于
∀i∈[1,N)
∀
i
∈
[
1
,
N
)
,都有
ai<ai+1
a
i
<
a
i
+
1
。因此如果当前数列不是目标数列,一定
∃ i∈[1,n)
∃
i
∈
[
1
,
n
)
使得
ai>ai+1
a
i
>
a
i
+
1
,那么
ai
a
i
和
ai+1
a
i
+
1
就构成了一对逆序对,我们需要一次操作交换这两个数。这样周而复始地进行交换操作,最终操作数量就是逆序对对数。
这个基本问题就可以衍生出许多问题,比如说 NOIP2013花匠 [题解],又比如这道题。
这道题把一个
1
1
到 的排列变成了两个
1
1
到 的排列相混合,于是出现了一个问题:我们甚至都不知道最终数列的状态是怎样的。
假设现在我们知道最终数列的状态,那么只需要像 NOIP2013花匠 一样扩展一下“逆序对”
(ai,aj)
(
a
i
,
a
j
)
的定义为:初始时
ai
a
i
在
aj
a
j
之后,目标状态下
ai
a
i
在
aj
a
j
之前的一对
(ai,aj)
(
a
i
,
a
j
)
。这样,答案仍旧是逆序对对数。
ok,现在我们只需要找到最优的目标状态了:
- dp状态:定义 dp[i][j] d p [ i ] [ j ] 表示目标状态中,前 i+j i + j 个数由 1 1 ~ 的黑球和 1 1 ~ 的白球混合排列而成(对于任意一种颜色的球,排列是升序的)时,最少的逆序对对数
- dp方程:
dp[i][j]=min(dp[i−1][j]+bi,j,dp[i][j−1]+wi,j)
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
−
1
]
[
j
]
+
b
i
,
j
,
d
p
[
i
]
[
j
−
1
]
+
w
i
,
j
)
,其中
bi,j
b
i
,
j
表示
1
1
~ 的白球和
1
1
~ 的黑球中,初始时在黑球
i
i
之后的球的数量; 同理
具体计算 bi,j b i , j 和 wi,j w i , j 可以在 dp 之前先 O(N2) O ( N 2 ) 预处理出所有位置关系,再通过二维前缀和优化使得能够在 dp 时 O(1) O ( 1 ) 得值 - dp顺序:由dp方程易知:顺序 for i 再 for j 即可
- 边界条件:由dp定义和dp顺序可知:dp[0][0] = 0
答案即是 dp[N][N] d p [ N ] [ N ]
时间复杂度: O(N2) O ( N 2 )
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x7fffffff;
const int N = 2005;
int n, a[N<<1], t, dp[N][N], g[N<<1][N<<1];
char c;
int cal(int x, int b, int w){
return g[x][b] - g[x-1][b] + g[x][w] - g[x][n] - g[x-1][w] + g[x-1][n];
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n << 1; i++){
scanf("%s%d", &c, &a[i]);
if(c == 'W') a[i] += n;
for(int j = 1; j < i; j++)
g[a[j]][a[i]] = 1;
}
for(int i = 1; i <= n << 1; i++)
for(int j = 1; j <= n << 1; j++)
g[i][j] += g[i-1][j] + g[i][j-1] - g[i-1][j-1];
memset(dp, 0x7f, sizeof dp);
dp[0][0] = 0;
for(int i = 0; i <= n; i++){
for(int j = 0; j <= n; j++){
if(!i && !j) continue;
dp[i][j] = min(i ? dp[i-1][j] + cal(i, i, j+n) : INF, j ? dp[i][j-1] + cal(j+n, i, j+n) : INF);
}
}
printf("%d\n", dp[n][n]);
return 0;
}