#include #include using namespace std; using ll = long long; constexpr ll llINF = 1'000'000'000'000'000'000LL; int main () { int N; cin >> N; vector X(N); for (int i = 0; i < N; i++) cin >> X[i]; vector A(N); for (int i = 0; i < N; i++) cin >> A[i]; vector A_cum(N+1); for (int i = 1; i <= N; i++) { A_cum[i] = A_cum[i-1] ^ A[i-1]; } // xorできるなら方がいい。 // 併合する区間をdpで管理できませんか? vector> dp(N, vector(N, llINF)); // dp[l][r] := 区間[l, r]を最適にマージした結果の最小コスト(整数の総和 + 移動コスト総和) auto rec = [&](auto self, int l, int r) -> ll { if (dp[l][r] < llINF) return dp[l][r]; if (l == r) return A[l]; ll res = llINF; // どこかでカット for (int sp = l; sp <= r-1; sp++) { res = min(res, self(self, l, sp) + self(self, sp+1, r)); } // どこにもカットを入れない res = min(res, (0LL + X[r] - X[l]) + (A_cum[r+1] ^ A_cum[l])); dp[l][r] = res; return dp[l][r]; }; cout << rec(rec, 0, N-1) << "\n"; }