比赛 2025.9.6 评测结果 AAATTTWWWTTTWWWTTTWWW
题目名称 Bessie s Function 最终得分 14
用户昵称 LikableP 运行时间 29.061 s
代码语言 C++ 内存使用 7.56 MiB
提交时间 2025-09-06 11:20:13
显示代码纯文本
#include <algorithm>
#include <cstdio>
#include <stack>

const int MAXN = 2e5 + 10;

int n;
int f[MAXN], cost[MAXN];
int ans = 0x7fffffff;

int k, a[MAXN], pre[MAXN];
void check() {
  int cost = 0;
  for (int i = 1; i <= k; ++i) {
    pre[i] = f[a[i]];
    f[a[i]] = a[i];
    cost += ::cost[a[i]];
  }

  bool ok = true;
  for (int i = 1; i <= n; ++i) {
    if (f[f[i]] != f[i]) ok = false;
  }

  for (int i = 1; i <= k; ++i) {
    f[a[i]] = pre[i];
  }

  if (ok) {
    ans = ::std::min(ans, cost);
  }
}

void dfs(int now) {
  if (now == k + 1) {
    return check();
  }

  for (int i = a[now - 1] + 1; i <= n - (k - now); ++i) {
    a[now] = i;
    dfs(now + 1);
  }
}

void Work1() {
  for (k = 1; k <= n; ++k) {
    dfs(1);
  }
  printf("%d\n", ans);
}

void dfs2(int now, int cost) {
  if (cost >= ans) return;

  if (now > n) {
    ans = ::std::min(ans, cost);
  }

  int pre = 0;
  if (f[f[now]] != f[now]) {
    pre = f[now];
    f[now] = now;
    dfs2(now + 1, cost + ::cost[now]);
    f[now] = pre;

    pre = f[f[now]];
    f[f[now]] = f[now];
    dfs2(now + 1, cost + ::cost[f[now]]);
    f[f[now]] = pre;
  } else {
    dfs2(now + 1, cost);
  }
}

void Work2() {
  dfs2(1, 0);
  printf("%d\n", ans);
}

struct NODE {
  int now, cost, pre, stamp;
};

::std::stack<NODE> st;
void Work3() {
  st.push({1, 0, 0, 0});
  while (!st.empty()) {
    auto &[now, cost, pre, stamp] = st.top();
    if (cost >= ans) {
      st.pop();
      continue;
    }
    if (now > n) {
      ans = ::std::min(ans, cost);
      continue;
    }
    if (stamp == 0) {
      if (f[f[now]] != f[now]) {
        pre = f[now];
        f[now] = now;
        st.push({now + 1, cost + ::cost[now], 0, 0});
        stamp = 1;
      } else {
        st.push({now + 1, cost, 0, 0});
        stamp = 114514;
      }
    } else if (stamp == 1) {
      f[now] = pre;
      pre = f[f[now]];
      f[f[now]] = f[now];
      st.push({now + 1, cost + ::cost[f[now]], 0, 0});
      stamp = 2;
    } else if (stamp == 2) {
      f[f[now]] = pre;
      stamp = 114514;
    } else if (stamp == 114514) {
      st.pop();
    }
  }
  printf("%d\n", ans);
}

int main() {
  freopen("Function.in", "r", stdin);
  freopen("Function.out", "w", stdout);
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &f[i]);
  }
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &cost[i]);
  }

  if (n <= 20) {
    Work3();
  } else {
    Work3();
  }
  return 0;
}