作业
题目背景:
分析:DP
啊咧咧,原来染色k次最多能够有2 * k - 1个连续段啊······
感觉自己get到了新姿势······然后想了一下,貌似这挺显然的····尴尬···言归正传,因为最多只有2 * k - 1个连续段,并且因为只有两种颜色,那么每个段非黑即白,并且小于等于2 * k - 1的任何一种情况都是可以得到的(手画一下证明吧),那么我们可以直接进行DP了,定义f[i][j][0/1]表示当前在i位置,已经染了j段,当前位置染成0/1的最优值,然后转移也就很清晰啦
f[i][j][k] = max(f[i - 1][j - 1][k ^ 1], f[i - 1][j][k]) + (a[i] == k);
Source:
/*
created by scarlyw
*/
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <cctype>
#include <vector>
#include <set>
#include <queue>
const int MAXN = 100000 + 10;
const int MAXK = 100 + 10;
int n, k;
int f[2][MAXK][2];
int a[MAXN];
inline void solve() {
scanf("%d%d", &n, &k), k = k * 2 - 1;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
int x = 1;
for (int i = 1; i <= n; ++i, x ^= 1)
for (int j = 1; j <= k; ++j) {
f[x][j][a[i]] = std::max(f[x ^ 1][j - 1][a[i] ^ 1],
f[x ^ 1][j][a[i]]) + 1;
f[x][j][a[i] ^ 1] = std::max(f[x ^ 1][j - 1][a[i]],
f[x ^ 1][j][a[i] ^ 1]);
}
int ans = 0;
for (int i = 1; i <= k; ++i) {
ans = std::max(f[x ^ 1][i][0], ans);
ans = std::max(f[x ^ 1][i][1], ans);
}
std::cout << ans;
}
int main() {
solve();
return 0;
}