这种需要手玩/多考虑几种情况的题不手玩不好好考虑就只有 20 tps
主要要考虑到可能会有相邻的两个红格子,
这样他们俩是可以通过不断放/跳棋子来 reach 任何一个格子
那之后怎么求总数?
其实就是 f[i] = f[i - 1] + f[i - 2] / f[i] = f[i + 1] + f[i + 2]
红色格子 f 值为 1,其余为 INF
由于 1 位置是初始棋子,不能算入
注意最大到 1e15,memset的数小了是会 GG 的
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
using namespace std;
typedef long long ll;
const int MAXN = 1005;
int n;
int seq[MAXN];
ll ans1, ans2;
ll f[MAXN];
bool hasnei;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &seq[i]);
ans1 = (n >> 1);
for (int i = 2; i < n; i += 2)
if (seq[i]) --ans1;
memset(f, 0x3f, sizeof(f));
for (int i = 3; i <= n; ++i) {
if (seq[i - 1] && seq[i]) hasnei = true;
}
if (!hasnei) {
printf("%lld\n%lld\n", ans1, (n >> 1) - ans1);
} else {
for (int i = 2; i <= n; ++i)
if (seq[i]) f[i] = 1ll;
ans2 = 0;
for (int i = 2; i <= n; ++i) {
f[i] = min(f[i], f[i - 1] + f[i - 2]);
}
for (int i = n; i >= 2; --i) {
f[i] = min(f[i], f[i + 1] + f[i + 2]);
}
for (int i = 2; i < n; i += 2) {
ans2 += f[i];
}
printf("0\n%lld\n", ans2);
}
return 0;
}