rt,用 dfs 实现的状压 dp,WA #6、#8、#9,都是比较大的数据点,小数据点基本都没问题。看不出来哪儿错了。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[105][50000][7], town[10], n, m;
char str[105];
int _merge(int pos) {
int ans = 0;
while (town[pos]) {
int l = pos, r = pos;
while (town[l] == town[l - 1] && l > 1)
l--;
while (town[r] == town[r + 1] && r < n)
r++;
if (l == r)
break;
ans += (r - l + 1) << town[pos];
for (int i = l; i <= r; i++)
if (i != pos)
town[i] = 0;
town[pos] = (town[pos] + 1) % 6;
}
return ans;
}
void make_town(int status) {
for (int i = 1; i <= n; i++) {
town[i] = status % 6;
status /= 6;
}
}
int make_status() {
int status = 0;
for (int i = n; i >= 1; i--)
status = status * 6 + town[i];
return status;
}
bool full() {
for (int i = 1; i <= n; i++)
if (!town[i])
return false;
return true;
}
int dfs(int status, int day, int wale) {
if (day == m + 1)
return 0;
int& dp = f[day][status][wale];
if (dp != -1)
return dp;
make_town(status);
if (full())
return 0;
if (wale) {
for (int i = 1; i <= n; i++)
if (!town[i]) {
town[i] = wale;
dp = max(dp, _merge(i) + dfs(make_status(), day, 0));
make_town(status);
}
} else
dp = max(dp, dfs(status, day + 1, str[day] - '0'));
for (int i = 1; i <= n; i++)
if (!town[i]) {
town[i] = str[day] - '0';
dp = max(dp, _merge(i) + dfs(make_status(), day + 1, wale));
make_town(status);
}
return dp;
}
int main() {
memset(f, -1, sizeof(f));
scanf("%d%d%s", &n, &m, str + 1);
printf("%d\n", dfs(0, 1, 0));
return 0;
}