zoukankan      html  css  js  c++  java
  • 洛谷P3622 动物园

    题意:给定一个n个元素的圈,m个条件。满足一个条件需要选某些元素或不选另一些元素。

    问最多能满足多少条件。每个条件所关联的元素,最远的两个距离不会超过5。

    解:想了半天......

    首先能想到断环成链DP。

    然后某个时刻灵光一闪,突然发现可以状压最近的5个位置......这样枚举开始位置做32次DP就行了!

    实现的时候发现只要枚举16种开始情况,状压4个位置...

    转移就是考虑下一个位置选/不选。

    注意细节......为什么有人20行A题,我写了160行呀...

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 
      6 const int N = 10010;
      7 
      8 struct Node {
      9     int p, fear, like;
     10     int a[5]; // 0 none  1 fear  2 like
     11 }node[5 * N];
     12 
     13 int f[N][16], n;
     14 std::vector<int> v[N];
     15 
     16 inline void exmax(int &a, int b) {
     17     a < b ? a = b : 0;
     18     return;
     19 }
     20 
     21 inline void out(int x, int tag) {
     22     printf(" ");
     23     for(int i = 0; i < tag; i++) {
     24         printf("%d", (x >> i) & 1);
     25     }
     26     printf(" ");
     27     return;
     28 }
     29 
     30 inline int check(Node x, int s) {
     31     for(int i = 0; i < 5; i++) {
     32         if(x.a[i] == 1 && ((s >> i) & 1)) {
     33             return 1;
     34         }
     35         if(x.a[i] == 2 && (((s >> i) & 1) == 0)) {
     36             return 1;
     37         }
     38     }
     39     return 0;
     40 }
     41 
     42 int main() {
     43 
     44     int m;
     45     scanf("%d%d", &n, &m);
     46     for(int i = 1, x; i <= m; i++) {
     47         scanf("%d%d%d", &node[i].p, &node[i].fear, &node[i].like);
     48         node[i].p += 4;
     49         while(node[i].p > n) {
     50             node[i].p -= n;
     51         }
     52         for(int j = 1; j <= node[i].fear; j++) {
     53             scanf("%d", &x);
     54             for(int k = 4, now = node[i].p + 1; k >= 0; k--) {
     55                 now--;
     56                 if(!now) {
     57                     now = n;
     58                 }
     59                 if(now == x) {
     60                     node[i].a[k] = 1;
     61                     break;
     62                 }
     63             }
     64         }
     65         for(int j = 1; j <= node[i].like; j++) {
     66             scanf("%d", &x);
     67             for(int k = 4, now = node[i].p + 1; k >= 0; k--) {
     68                 now--;
     69                 if(!now) {
     70                     now = n;
     71                 }
     72                 if(now == x) {
     73                     node[i].a[k] = 2;
     74                     break;
     75                 }
     76             }
     77         }
     78         v[node[i].p].push_back(i);
     79     }
     80     /// input
     81     int ans = 0;
     82     /// -----
     83     /// 01234
     84     for(int op = 0; op < 16; op++) { /// first four
     85         memset(f, 0, sizeof(f));
     86         for(int s = 0; s < 16; s++) {
     87             if(s != op) {
     88                 f[4][s] = -1;
     89             }
     90         }
     91 
     92         for(int i = 4; i < n; i++) {
     93             for(int s = 0; s < 16; s++) {
     94                 if(f[i][s] == -1) {
     95                     continue;
     96                 }
     97                 /// f[i][s] -> f[i + 1][t]
     98                 
     99                 int t = s >> 1, temp = f[i][s]; /// put 0  don't move
    100                 for(int j = 0; j < v[i + 1].size(); j++) {
    101                     /// node[v[i + 1][j]]  and  s
    102                     temp += check(node[v[i + 1][j]], s);
    103                 }
    104                 exmax(f[i + 1][t], temp);
    105                 // -------------------------------------
    106                 t = t | (1 << 3); /// put 1  move
    107                 temp = f[i][s];
    108                 for(int j = 0; j < v[i + 1].size(); j++) {
    109                     temp += check(node[v[i + 1][j]], s | (1 << 4));
    110                 }
    111                 exmax(f[i + 1][t], temp);
    112             }
    113         }
    114         for(int s = 0; s < 16; s++) {
    115             /// f[n][s]
    116             int temp = f[n][s], now = s << 1;
    117             for(int i = 0; i < 4; i++) {
    118                 now = (now >> 1) + (((op >> i) & 1) << 4);
    119                 for(int j = 0; j < v[i + 1].size(); j++) {
    120                     temp += check(node[v[i + 1][j]], now);
    121                 }
    122             }
    123             exmax(ans, temp);
    124         }
    125     }
    126     printf("%d
    ", ans);
    127     return 0;
    128 }
    AC代码
  • 相关阅读:
    Java并发编程:如何创建线程?
    Java并发编程:volatile关键字解析
    Java并发编程:深入剖析ThreadLocal
    Java并发编程:同步容器
    Java ConcurrentModificationException异常原因和解决方法
    Java并发编程:并发容器之ConcurrentHashMap
    Java并发编程:并发容器之CopyOnWriteArrayList
    Java并发编程:Callable、Future和FutureTask
    rest-framework频率组件
    rest-framework的权限组件
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10383076.html
Copyright © 2011-2022 走看看