Description
Solution
每个人能看到的动物只有5个,所以我们可以将这个进行状压,定义f[i][j]表示从第i开始的五个动物状态压缩后(移走或不移走)为j的最优结果
那么转移方程可以得到
其中,val表示这一步转移所获得的收益,由于动物园是环形的,所以初状态等于末状态,我们枚举末状态,取出最大值即可
Code
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline int read() { 5 int ret = 0; 6 int op = 1; 7 char c = getchar(); 8 while (c < '0' || c > '9') {if (c == '-') op = -1; c = getchar();} 9 while (c <= '9' && c >= '0') ret = ret * 10 + c - '0', c = getchar(); 10 return ret * op; 11 } 12 int n, m, ans; 13 int f[10010][1 << 6], val[10010][1 << 6]; 14 int main() { 15 n = read(); m = read(); 16 for (int i = 1; i <= m; ++i) { 17 int a = read(), b = read(), c = read(); 18 int x = 0, y = 0, now; 19 for (int j = 1; j <= b; ++j) { 20 now = read(); 21 now = (now - a + n) % n; 22 x |= 1 << now; 23 } 24 for (int j = 1; j <= c; ++j) { 25 now = read(); 26 now = (now - a + n) % n; 27 y |= 1 << now; 28 } 29 for (int j = 0; j < (1 << 5); ++j) 30 if ((j & x) || ((~j) & y)) val[a][j]++; 31 } 32 for (int i = 0; i < (1 << 5); ++i) { 33 memset(f[0], 128, sizeof(f[0])); 34 f[0][i] = 0; 35 for (int j = 1; j <= n; ++j) { 36 for (int s = 0; s < (1 << 5); ++s) 37 f[j][s] = max(f[j - 1][(s & 15) << 1], f[j - 1][(s & 15) << 1 | 1]) + val[j][s]; 38 } 39 ans = max(ans, f[n][i]); 40 } 41 printf("%d ", ans); 42 return 0; 43 }