染色
zhujiangyuan · · 题解
\mathcal O(n^3)
设
转移:枚举
根据定义,
具体地,令
此做法时间复杂度
void solve () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
f[i][j] = 0;
for (int i = 1; i <= n; ++i)
s[i] = s[i - 1] + (a[i] == a[i - 1]) * a[i];
LL ans = 0;
for (int i = 1; i <= n; ++i) {
f[i][0] = s[i];
for (int j = 1; j < i; ++j) {
for (int k = 0; k < j; ++k)
f[i][j] = max (f[i][j], f[j][k] + s[i] - s[j + 1] + (a[j + 1] == a[k]) * a[k]);
}
}
for (int i = 0; i <= n; i++)
ans = max (ans, f[n][i]);
cout << ans << '\n';
}
\mathcal O(n^2) solution 1
观察以下转移:
for (int k = 0; k < j; ++k)
f[i][j] = max (f[i][j], f[j][k] + s[i] - s[j + 1] + (a[j + 1] == a[k]) * a[k]);
发现
考虑提出
我们得到新的转移:
此做法时间复杂度
void solve () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
f[i][j] = 0, g[i] = 0;
for (int i = 1; i <= n; ++i)
s[i] = s[i - 1] + (a[i] == a[i - 1]) * a[i];
LL ans = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < i; ++j) {
f[i][j] = g[j] + s[i];
}
for (int k = 0; k < i; ++k)
g[i] = max (g[i], f[i][k] - s[i + 1] + (a[i + 1] == a[k]) * a[k]);
}
for (int i = 0; i <= n; i++)
ans = max (ans, f[n][i]);
cout << ans << '\n';
}
\mathcal O(n^2) solution 2
考虑优化空间。
观察上面的代码,发现其中出现的
考虑将原来的
设
此做法时间复杂度
void solve () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i <= n; ++i) f[i] = 0, g[i] = 0;
for (int i = 1; i <= n; ++i)
s[i] = s[i - 1] + (a[i] == a[i - 1]) * a[i];
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < i; ++j) f[i] = max (f[i], g[j] + s[i]);
for (int k = 0; k < i; ++k) g[i] = max (g[i], g[k] + s[i] - s[i + 1] + (a[i + 1] == a[k]) * a[k]);
}
cout << f[n] << '\n';
}
\mathcal O(n)
看这个式子:
将
上面提到
将
然后就做完了。
此做法时间复杂度
void solve () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i <= n; ++i) f[i] = g[i] = mx[i] = 0, t[a[i]] = 0;
for (int i = 1; i <= n; ++i)
s[i] = s[i - 1] + (a[i] == a[i - 1]) * a[i];
for (int i = 1; i <= n; ++i) {
f[i] = mx[i - 1] + s[i];
g[i] = max (mx[i - 1], t[a[i + 1]]) + s[i] - s[i + 1];
t[a[i]] = max (t[a[i]], g[i] + a[i]);
mx[i] = max (mx[i - 1], g[i]);
}
cout << f[n] << '\n';
}