Problem p03357 (C++)

Buggy submission (status: Runtime Error):

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string.h>
using namespace std;
typedef long long ll;
const int maxn = 3000 + 5;
int dp[maxn][maxn];
int costB[maxn][maxn];
int costR[maxn][maxn];
int id[maxn * 2]; // 棋子的编号
int n;
string str;
map<int, int> posB, posR;
void pre_cost() // 初始化costB，costR
{
  // costB[i][1~n] 在第i个棋子前面 编号为1~n黑棋子的出现次数
  // costR[i][1~n] 在第i个棋子前面 编号为1~n白棋子的出现次数
  for (int i = 0; i < 2 * n; i++) {
    for (int j = 0; j < i;
         j++) { // costB[i][j] 在第i个棋子前面 id为j的黑棋子个数
      int index = id[j];
      if (str[j] == 'B') {
        costB[i][index]++;
      } else {
        costR[i][index]++;
      }
    }
  }
  // 对costB[i][1~n]，costA[i][1~n]做前缀和后
  // costB[i][j]代表，第i个棋子前面，编号<=j的黑棋子个数
  for (int i = 0; i < n * 2; i++) {
    for (int j = 1; j <= n; j++) {
      costR[i][j] += costR[i][j - 1];

      costB[i][j] += costB[i][j - 1];
    }
  }
}
int cost_B(int i, int j) { // 加入第i个黑棋，且1~j个白棋已经排好序的代价
  int Cost = 0;
  int pos = posB[i];
  // 计算 pos 位置前，值大于i的黑棋，值大于j的白棋的数量
  Cost = pos - (costB[pos][i] + costR[pos][j]);
  return Cost;
}
int cost_R(int i, int j) { // 加入第i个白棋，且1~j个白棋已经排好序的代价
  int Cost = 0;
  int pos = posR[i];
  // 计算 pos 位置前，值大于i的白棋，值大于j的黑棋的数量
  Cost = pos - (costR[pos][i] + costB[pos][j]);
  return Cost;
}

void init() {
  cin >> n;

  cin >> str;
  for (int i = 0; i < 2 * n; i++) {
    cin >> id[i];
    if (str[i] == 'B') {
      posB[id[i]] = i;
    } else {
      posR[id[i]] = i;
    }
  }
}
void init1() {
  cin >> n;
  str = "";
  for (int i = 0; i < 2 * n; i++) {
    char ch;
    cin >> ch;
    cin >> id[i];
    str += ch;

    if (str[i] == 'B') {
      posB[id[i]] = i;
    } else {
      posR[id[i]] = i;
    }
  }
  // cout<<str;
}
/*
4
BWBWBWBW

*/
int main() {
  init1();
  // cout<<n<<endl;
  pre_cost();
  memset(dp, 0x3f, sizeof(dp));
  dp[0][0] = 0;
  // dp[1][0]=cost_B(1,0);
  // dp[0][1]=cost_R(1,0);
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      // if (i == j && i == 0)
      // {
      //     continue;
      // }
      if (i - 1 >= 0) {
        dp[i][j] = min(dp[i - 1][j] + cost_B(i, j), dp[i][j]);
      }
      if (j - 1 >= 0) {
        dp[i][j] = min(dp[i][j], dp[i][j - 1] + cost_R(j, i));
      }
      //
      // dp[i][j] = min(dp[i - 1][j] + cost_B(i, j), dp[i][j - 1] + cost_R(j,
      // i));
      // cout<<dp[i][j]<<" "<<i<<" "<<j<<endl;
    }
  }
  cout << dp[n][n];

  return 0;
}

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string.h>
using namespace std;
typedef long long ll;
const int maxn = 4000 + 5;
int dp[maxn][maxn];
int costB[maxn][maxn];
int costR[maxn][maxn];
int id[maxn * 2]; // 棋子的编号
int n;
string str;
map<int, int> posB, posR;
void pre_cost() // 初始化costB，costR
{
  // costB[i][1~n] 在第i个棋子前面 编号为1~n黑棋子的出现次数
  // costR[i][1~n] 在第i个棋子前面 编号为1~n白棋子的出现次数
  for (int i = 0; i < 2 * n; i++) {
    for (int j = 0; j < i;
         j++) { // costB[i][j] 在第i个棋子前面 id为j的黑棋子个数
      int index = id[j];
      if (str[j] == 'B') {
        costB[i][index]++;
      } else {
        costR[i][index]++;
      }
    }
  }
  // 对costB[i][1~n]，costA[i][1~n]做前缀和后
  // costB[i][j]代表，第i个棋子前面，编号<=j的黑棋子个数
  for (int i = 0; i < n * 2; i++) {
    for (int j = 1; j <= n; j++) {
      costR[i][j] += costR[i][j - 1];

      costB[i][j] += costB[i][j - 1];
    }
  }
}
int cost_B(int i, int j) { // 加入第i个黑棋，且1~j个白棋已经排好序的代价
  int Cost = 0;
  int pos = posB[i];
  // 计算 pos 位置前，值大于i的黑棋，值大于j的白棋的数量
  Cost = pos - (costB[pos][i] + costR[pos][j]);
  return Cost;
}
int cost_R(int i, int j) { // 加入第i个白棋，且1~j个白棋已经排好序的代价
  int Cost = 0;
  int pos = posR[i];
  // 计算 pos 位置前，值大于i的白棋，值大于j的黑棋的数量
  Cost = pos - (costR[pos][i] + costB[pos][j]);
  return Cost;
}

void init() {
  cin >> n;

  cin >> str;
  for (int i = 0; i < 2 * n; i++) {
    cin >> id[i];
    if (str[i] == 'B') {
      posB[id[i]] = i;
    } else {
      posR[id[i]] = i;
    }
  }
}
void init1() {
  cin >> n;
  str = "";
  for (int i = 0; i < 2 * n; i++) {
    char ch;
    cin >> ch;
    cin >> id[i];
    str += ch;

    if (str[i] == 'B') {
      posB[id[i]] = i;
    } else {
      posR[id[i]] = i;
    }
  }
  // cout<<str;
}
/*
4
BWBWBWBW

*/
int main() {
  init1();
  // cout<<n<<endl;
  pre_cost();
  memset(dp, 0x3f, sizeof(dp));
  dp[0][0] = 0;
  // dp[1][0]=cost_B(1,0);
  // dp[0][1]=cost_R(1,0);
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      // if (i == j && i == 0)
      // {
      //     continue;
      // }
      if (i - 1 >= 0) {
        dp[i][j] = min(dp[i - 1][j] + cost_B(i, j), dp[i][j]);
      }
      if (j - 1 >= 0) {
        dp[i][j] = min(dp[i][j], dp[i][j - 1] + cost_R(j, i));
      }
      //
      // dp[i][j] = min(dp[i - 1][j] + cost_B(i, j), dp[i][j - 1] + cost_R(j,
      // i));
      // cout<<dp[i][j]<<" "<<i<<" "<<j<<endl;
    }
  }
  cout << dp[n][n];

  return 0;
}