abc400_f 题解
beyoursven · · 题解
题意
给定一个大小为
思路
根据数据范围,可以猜测使用区间 dp 求解。先考虑解决线性序列上的问题。
经过推导可以发现,两次染色的区间可以是不相交或者包含关系,但不可能是非包含但相交的关系。
定义
对于不相交的情况,显然有:
对于包含情况,就是第一步把区间
定义
包含情况只可能出现在
考虑如何维护
当区间
我们还可以考虑当区间
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 4e2 + 1;
const ll INF = 1e18;
int n, c[2 * MAXN], x[MAXN];
ll ans = LLONG_MAX, dp[2 * MAXN][2 * MAXN], g[2 * MAXN][2 * MAXN];
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> c[i];
c[i + n] = c[i];
}
for (int i = 1; i <= n; i++) {
cin >> x[i];
}
for (int i = 1; i <= 2 * n; i++) {
dp[i][i] = g[i][i] = x[c[i]] + 1;
}
for (int len = 2; len <= n; len++) {
for (int i = 1, j = i + len - 1; j <= 2 * n; i++, j++) {
dp[i][j] = INF, g[i][j] = x[c[i]] + j - i + 1 + dp[i + 1][j];
for (int k = i; k < j; k++) {
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
if (c[i] == c[k + 1]) {
g[i][j] = min(g[i][j], g[i][k] + g[k + 1][j] - x[c[i]]);
}
}
if (c[i] == c[j]) {
dp[i][j] = min(dp[i][j], g[i][j]);
}
}
}
for (int i = 1; i <= n; i++) {
ans = min(ans, dp[i][i + n - 1]);
}
cout << ans;
return 0;
}