0
点赞
收藏
分享

微信扫一扫

Luogu P3622 [APIO2007]动物园


题目链接:​​传送门​​

表示从处理到这个围栏且从开始的五个围栏状态为的最多小朋友数
一定可以从转移过来,只需要再考虑当前多出来的这个围栏的状态即可
转移方程:
就是这个围栏选和不选的情况
是挑出的后位,就是加上新的一位,就是新的一位是(选这个围栏)
是在位置且连续个位置的状态是时有几个小朋友会开心
预处理也不难,把输入的集合存起来判断一下有几个小朋友开心就好
要注意是一个环,所以位置需要
dp的时候需要枚举最后位置的结束状态,因为位置和位置是连起来的,所以这两个地方的状态需要吻合

#include <bits/stdc++.h>

using namespace std;
int N, C, E, F, L, x, ans, f[50010][32], w[50010][32];

int main(int argc, char const *argv[]) {
cin >> N >> C;
for (int i = 1; i <= C; i++) {
scanf("%d%d%d", &E, &F, &L); int fear = 0, like = 0;
for (int j = 1; j <= F; j++) scanf("%d", &x), fear |= (1 << ((x - E + N) % N));
for (int j = 1; j <= L; j++) scanf("%d", &x), like |= (1 << ((x - E + N) % N));
for (int j = 0; j < 32; j++) if ((~j & like) or (fear & j)) w[E][j]++;
}
for (int s = 0; s < 32; s++) {
memset(f[0], -0x3f, sizeof f[0]); f[0][s] = 0;
for (int j = 1; j <= N; j++) for (int k = 0; k < 32; k++)
f[j][k] = max(f[j - 1][(k & 15) << 1], f[j - 1][(k & 15) << 1 | 1]) + w[j][k];
ans = max(ans, f[N][s]);
}
cout << ans << endl;
}


举报

相关推荐

0 条评论