bzoj 1151: [CTSC2007]动物园zoo
思路:因为每个人最多只能看到五个动物,我们考虑将其状压,f[ i ][ s ] 表示到了第 i 个位置, i, i + 1, i + 2, i + 3, i + 4这四个动物的状态为s,
此时的最大值。 因为它是一个环,所以我们考虑枚举前4位,这样就能dp啦,dp[i][s] = max(dp[i - 1][(15 & s) << 1], dp[i - 1][(15 & s) << 1 | 1]) + val[i][s];
val[ i ]][ s ] 是预处理出来,在i这个位置的人在s这个状态的贡献。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define piii pair<int, pair<int,int>> 8 9 using namespace std; 10 11 const int N=10000+7; 12 const int M=1e4+7; 13 const int inf=0x3f3f3f3f; 14 const LL INF=0x3f3f3f3f3f3f3f3f; 15 const int mod=1e9 + 7; 16 17 int n, m, val[N][32], dp[N][32]; 18 int main() { 19 scanf("%d%d", &n, &m); 20 for(int k = 1; k <= m; k++) { 21 int pos; scanf("%d", &pos); 22 int cnt1, cnt2, s1 = 0, s2 = 0; 23 scanf("%d%d", &cnt1, &cnt2); 24 for(int i = 1; i <= cnt1; i++) { 25 int x; scanf("%d", &x); 26 s1 |= 1 << ((x - pos + n) % n); 27 } 28 for(int i = 1; i <= cnt2; i++) { 29 int x; scanf("%d", &x); 30 s2 |= 1 << ((x - pos + n) % n); 31 } 32 33 for(int j = 0; j < 32; j++) { 34 if(j & s1 || (31 ^ j) & s2) { 35 val[pos][j]++; 36 } 37 } 38 } 39 40 int ans = 0; 41 for(int s1 = 0; s1 < 16; s1++) { 42 for(int i = 0; i < 32; i++) dp[0][i] = -inf; 43 dp[0][s1 << 1] = 0; 44 for(int i = 1; i <= n; i++) { 45 for(int s = 0; s < 32; s++) { 46 dp[i][s] = max(dp[i - 1][(15 & s) << 1], dp[i - 1][(15 & s) << 1 | 1]) + val[i][s]; 47 } 48 } 49 ans = max(ans, max(dp[n][s1 << 1], dp[n][s1 << 1 | 1])); 50 } 51 52 printf("%d\n", ans); 53 return 0; 54 } 55 /* 56 */