列表

详情


NC50527. 动物园

描述

新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一种动物。如下图所示:
zoo1.png你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事——有些小朋友喜欢某些动物,而有些小朋友则害怕某些动物。例如,Alex喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的狮子。而Polly会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。
你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。
每个小朋友站在大围栏圈的外面,可以看到连续的5个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴:
至少有一个他害怕的动物被移走;至少有一个他喜欢的动物没被移走。例如,考虑下图中的小朋友和动物:zoo2.png
假如你将围栏4和12的动物移走。Alex和Ka-Shu将很高兴,因为至少有一个他们害怕的动物被移走了。这也会使Chaitanya高兴,因为他喜欢的围栏6和8中的动物都保留了。但是,Polly和Hwan将不高兴,因为他们看不到任何他们喜欢的动物,而他们害怕的动物都还在。这种安排方式使得三个小朋友高兴。
现在换一种方法,如果你将围栏4和6中的动物移走,Alex和Polly将很高兴,因为他们害怕的动物被移走了。Chaitanya也会高兴,虽然他喜欢的动物6被移走了,他仍可以看到围栏8里面他喜欢的动物。同样的Hwan也会因可以看到自己喜欢的动物12而高兴。唯一不高兴的只有Ka-Shu。
如果你只移走围栏13中的动物,Ka-Shu将高兴,因为有一个他害怕的动物被移走了,Alex,Polly,Chaitanya和Hwan也会高兴,因为他们都可以看到至少一个他们喜欢的动物。所以有5个小朋友会高兴。这种方法使得了最多的小朋友高兴。



输入描述

输入的第一行包含两个整数N,C,用空格分隔。N是围栏数,C是小朋友的个数。围栏按照顺时针的方向编号为1,2,3,…,N。
接下来的C行,每行描述一个小朋友的信息,以下面的形式给出:
其中:E表示这个小朋友可以看到的第一个围栏的编号,换句话说,该小朋友可以看到的围栏为E,E+1,E+2,E+3,E+4。注意,如果编号超过N将继续从1开始算。如:当N=14,E=13时,这个小朋友可以看到的围栏为13,14,1,2和3。
F表示该小朋友害怕的动物数。L表示该小朋友喜欢的动物数。
围栏中包含该小朋友害怕的动物。围栏中包含该小朋友喜欢的动物。
是两两不同的整数,而且所表示的围栏都是该小朋友可以看到的。
小朋友已经按照他们可以看到的第一个围栏的编号从小到大的顺序排好了(这样最小的E对应的小朋友排在第一个,最大的E对应的小朋友排在最后一个)。
注意可能有多于一个小朋友对应的E是相同的。

输出描述

仅输出一个数,表示最多可以让多少个小朋友高兴。

示例1

输入:

14 5
2 1 2 4 2 6
3 1 1 6 4
6 1 2 9 6 8
8 1 1 9 12
12 3 0 12 13 2

输出:

5

说明:

样例1给出了前面描述的示例情形。它使得所有小朋友(C=5)高兴。

示例2

输入:

12 7
1 1 1 1 5
5 1 1 5 7
5 0 3 5 7 9
7 1 1 7 9
9 1 1 9 11
9 3 0 9 11 1
11 1 1 11 1

输出:

6

说明:

样例2给出了这样的情形,要使得所有小朋友(C=7)都高兴是不可能的。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java 解法, 执行用时: 1659ms, 内存消耗: 55176K, 提交时间: 2021-10-07 20:05:43

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

public class Main {
    static long mod = 1;

    static class SegmentTree {

        static int l;
        static int r;
        static long v;
        static Node root;
        static long cache[];

        static void build(long f[]) {
            cache = f;
            root = new Node(0, f.length - 1);
        }

        static long query(int left, int right) {
            l = left;
            r = right;
            return root.query();
        }


        static void add_range(int left, int right, long value) {
            l = left;
            r = right;
            v = value;
            root.add_range();
        }

        static void multi_range(int left, int right, long value) {
            l = left;
            r = right;
            v = value;
            root.multi_range();
        }

        static void set_range(int left, int right) {
            l = left;
            r = right;
            //     root.set_range();
        }


        static class Node {
            //   boolean seted;
            long setv = 1;
            long add = 0;
            int left;
            int right;
            long min_value;
            Node l_node;
            Node r_node;

            public Node(int l, int r) {
                left = l;
                right = r;
                if (l == r) {
                    min_value = cache[l];
                } else {
                    int mid = (l + r) >> 1;
                    l_node = new Node(l, mid);
                    r_node = new Node(mid + 1, r);
                    pollup();
                }
            }

            private long query() {
                if (l <= left && r >= right) {
                    return min_value;
                } else if (l > right || r < left) {
                    return 0;
                } else {
                    pushdown();
                    long v1 = l_node.query();
                    long v2 = r_node.query();
                    pollup();
                    return (v1+v2)%mod;
                }
            }

            private void add_range() {
                if (l <= left && r >= right) {
                    add += v;
                    min_value += v *(right-left+1);
                } else if (l > right || r < left) {
                    return;
                } else {
                    pushdown();
                    l_node.add_range();
                    r_node.add_range();
                    pollup();
                }
            }

            private void multi_range() {
                if (l <= left && r >= right) {
                    setv *= v;
                    add = add*v;
                    min_value  = (min_value * v) % mod;
                } else if (l > right || r < left) {
                    return;
                } else {
                    pushdown();
                    l_node.multi_range();
                    r_node.multi_range();
                    pollup();
                }
            }



//            private void set_range() {
//                if (l <= left && r >= right) {
//                    seted = true;
//                    setv = v;
//                    add = 0;
//                    min_value = v;
//                } else if (l > right || r < left) {
//                    return;
//                } else {
//                    pushdown();
//                    l_node.set_range();
//                    r_node.set_range();
//                    pollup();
//                }
//            }

            // first multi, then add
            private void pushdown() {
                if (setv!=1) {

                    l_node.setv *= setv;
                    r_node.setv *= setv;
                    l_node.min_value = l_node.min_value*setv%mod;
                    r_node.min_value = r_node.min_value*setv%mod;
                    l_node.add = l_node.add*setv;
                    r_node.add = r_node.add*setv;
                    setv = 1;
                }
                if (add != 0) {
                    l_node.add += add;
                    r_node.add += add;
                    l_node.min_value += add * (l_node.right - l_node.left + 1 );
                    l_node.min_value %= mod;
                    r_node.min_value += add * (r_node.right - r_node.left + 1 );
                    r_node.min_value %= mod;
                    add = 0;
                }
            }

            private void pollup() {
                min_value = (l_node.min_value + r_node.min_value)%mod;
            }


        }
    }


    static class Task {

        public static String roundS(double result, int scale) {
            String fmt = String.format("%%.%df", scale);
            return String.format(fmt, result);
//        DecimalFormat df = new DecimalFormat("0.000000");
//        double result = Double.parseDouble(df.format(result));
        }



        long[][] mult(long a[][],long b[][], long mod){
            int l1 = a.length;
            int l2 = b.length;
            int l3 = b[0].length;
            long r[][] = new long[l1][l3];
            for(int i=0;i<l1;++i){
                for(int j=0;j<l2;++j){
                    for(int k=0;k<l3;++k){
                        r[i][k] = (r[i][k] + a[i][j] * b[j][k]%mod)%mod;
                    }
                }
            }
            return r;
        }

        long[][] add(long a[][],long b[][],long mod){
            int l1 = a.length;
            int l2 = a[0].length;

            long r[][] = new long[l1][l2];
            for(int i=0;i<l1;++i){
                for(int j=0;j<l2;++j){
                    r[i][j] = (a[i][j] + b[i][j])%mod;
                }
            }
            return r;

        }

        long[][] ones(int len){
            long r[][] = new long[len][len];
            for(int i=0;i<len;++i){
                r[i][i] = 1L;
            }
            return r;
        }

        long[][] quick(long a[][], int times,long mod){
            int len = a.length;
            long ans[][] = ones(len);

            while(times>0){
                if((times&1)==1) {
                    ans = mult(ans, a, mod);
                }
                a = mult(a, a, mod);
                times >>= 1;
            }

            return ans;
        }


        long mb = 1535002967L;
        long p  = 1331;
        long hash[];long f[];

        long getHash(int i,int l){
            // str from i to (i+len-1)
            return (mb + (hash[i+l]  - f[l]*hash[i] )%mb)%mb;
        }



        void hash(String s){
            int len = s.length();
            hash = new long[len+1];
            f = new long[len+1];
            hash = new long[len+1];
            f[0] = 1;
            for(int j = 1;j<=len;++j){
                hash[j] = (hash[j-1]*p + s.charAt(j-1))%mb;
                f[j] = (f[j-1]*p)%mb;
            }

//            for(int i=0;i<len;++i){
//                for(int l = 0;i+l<=len;++l){
//                    long v = getHash(i,l);
//                }
//            }
        }




        int[] to,ne,h;
        void add(int u,int v){
            to[ct] = v;
            ne[ct] = h[u];
            h[u] =  ct++;
        }

        int ct= 0;
        int n;
        int m;

        void init(){
            h = new int[n];Arrays.fill(h,-1);
            to = new int[m];
            ne = new int[m];
        }





//        int go(int l,int r,int a[]){
//            if(l>r) return 0;
//
//            for(int i=1;i<a[l];++i){
//
//            }
//        }



        public void solve(int testNumber, InputReader in, PrintWriter out) {

            int n = in.nextInt();
            int len = in.nextInt();

            int e[] = new int[len];
            int f[] = new int[len];
            int l[] = new int[len];



            List<int[]>[] g = new List[n];
            for(int i=0;i<n;++i){
                g[i] = new ArrayList<>();
            }


            for(int i=0;i<len;++i){
                e[i] = in.nextInt();
                f[i] = in.nextInt();
                l[i] = in.nextInt();
                int fr = 0;
                int lv = 0;
                for(int j=0;j<f[i];++j){
                    fr |= 1<<((in.nextInt() - e[i] + n)%n);
                }
                for(int j=0;j<l[i];++j){
                    lv |= 1<< ((in.nextInt() - e[i] + n)%n);
                }
                g[e[i]-1].add(new int[]{fr,lv});
            }



            int filter = (1<<5)-1;

            int r = 0;
            for(int st=0;st<1<<4;++st) {
                int dp[][] = new int[n][1<<5];

               for(int i=0;i<n;++i){
                   for(int c=0;c<1<<5;++c) {
                       if (i == 0 && (c&((1<<4)-1) )!= st) {
                           continue;
                       }
                       int s = 0;
                       for(int[] ck: g[i]){
                           if((ck[1]&c)!=0||(ck[0]&(filter-c))!=0){
                               s +=1;
                           }
                       }

                       dp[i][c] = Math.max(dp[i][c], s + (i>=1?dp[i-1][(c<<1)&filter]:0));
                       dp[i][c] = Math.max(dp[i][c], s + (i>=1?dp[i-1][((c<<1)&filter)|1]:0));
                   }
               }

               r = Math.max(r,  dp[n-1][(st<<1)]);
                r = Math.max(r,  dp[n-1][(st<<1)|1]);

            }

            out.print(r);



        }







//        int t = in.nextInt();
//        int n = in.nextInt();
//        int m = in.nextInt();
//
//        ct = 0;
//        h = new int[n];Arrays.fill(h,-1);
//        if(t==1) {
//            to = new int[m * 2];
//            ne = new int[m * 2];
//
//            fob = new boolean[m * 2];
//        }else{
//            to = new int[m];
//            ne = new int[m];
//
//        }
//
//
//        int rd[] = new int[n];
//        int cd[] = new int[n];
//        li = new int[m];
//        tp = m-1;
//
//        int rt=  0;
//
//        for(int i=0;i<m;++i){
//            int u = in.nextInt()-1;
//            int v = in.nextInt()-1;
//            add(u,v);
//            if(t==1){
//                add(v,u);
//            }
//            cd[u]++;
//            rd[v]++;
//            rt = u;
//        }
//
//        if(t==2){
//
//            for(int i=0;i<n;++i){
//                if(rd[i]!=cd[i]){
//                    out.println("NO");return;
//                }
//            }
//        }else{
//
//            for(int i=0;i<n;++i){
//                if(((rd[i]+cd[i])%2)>0){
//                    out.println("NO");return;
//                }
//            }
//
//        }
//
//
//
//        dfs11(rt, t);
//
//
//
//        if(tp!=-1){
//            out.print("NO");
//            return;
//        }
//
//        out.println("YES");
//
//        for(int i=0;i<m;++i){
//            out.print(li[i]+ " ");
//        }


//            int f1[][] = new int[q][3];
//
//            for(int i=0;i<q;++i){
//                for(int j=0;j<3;++j){
//                    f1[i][j] = in.nextInt();
//                }
//            }
//
//
//                int h[] = new int[n+1];
//
//                Arrays.fill(h,-1);
//
//
//                int ne[] = new int[p*2+q];
//                int to[] = new int[p*2+q];
//                int wt[] = new int[p*2+q];
//                ct = 0;
//            Func fk = (int x,int y,int z) -> {
//                to[ct] = y;
//                ne[ct] = h[x];
//                wt[ct] = z;
//                h[x] = ct++;
//            };
//
//                for(int i=0;i<p;++i){
//                    int u =  f[i][0];
//                    int v =  f[i][1];
//
//
//
//
//                        fk.add(u,v,f[i][2]);
//                        fk.add(v,u,f[i][2]);
//                }
//
//            for(int i=0;i<q;++i){
//                int u =  f1[i][0];
//                int v =  f1[i][1];
//
//
//
//
//                fk.add(u,v,f1[i][2]);
//            }


//                int dp[] = new int[n+1];
//                Arrays.fill(dp,100000000);
//                dp[s] = 0;
//
//
//                PriorityQueue<int[]> qu = new PriorityQueue<>(Comparator.comparingInt((x)->x[0]));
//                qu.add(new int[]{0,s});
//                while(qu.size()>0){
//                    int cc[] = qu.poll();
//                    int cur =  cc[1];
//                    if(cc[0]!=dp[cur]) continue;
//                    for(int j = h[cur];j!=-1;j=ne[j]){
//                        int v = to[j];
//                        if(dp[v] > dp[cur] + wt[j]){
//                            dp[v] = dp[cur] + wt[j];
//                            qu.offer(new int[]{dp[v],v});
//                        }
//                    }
//                }
//
//                for(int j=1;j<=n;++j){
//                    if(dp[j]==100000000){
//                        out.println("NO PATH");
//                    }else{
//                        out.println(dp[j]);
//                    }
//                }


//                for(int t=0;t<5;++t) {
//                    int at = fi[t];
//                    dp[at][t] = 0;
//                    PriorityQueue<int[]> q = new PriorityQueue<>(Comparator.comparingInt((x) -> x[0]));
//                    q.offer(new int[]{0, at});
//                    while (q.size() > 0) {
//                        int cur[] = q.poll();
//                        if (cur[0] != dp[cur[1]][t]) continue;
//                        int i = cur[1];
//                        for (int j = h[i]; j != -1; j = ne[j]) {
//                            int v = to[j];
//                            if (dp[i][t] + wt[j] < dp[v][t]) {
//                                dp[v][t] = dp[i][t] + wt[j];
//                                q.offer(new int[]{dp[v][t], v});
//                            }
//                        }
//                    }
//                }
//                int cl[] = new int[]{0,1,2,3,4};
//                int rs = Integer.MAX_VALUE;
//                do{
//                    int s= dp[1][cl[0]];
//                    for(int j=0;j<4;++j){
//                        int nxt = fi[cl[j+1]];
//                        s += dp[nxt][cl[j]];
//                    }
//                    rs = Math.min(rs,s);
//
//
//                }while(next_perm(cl));
//
//                out.print(rs);


        boolean next_perm(int[] a) {
            int len = a.length;
            for (int i = len - 2, j = 0; i >= 0; --i) {
                if (a[i] < a[i + 1]) {
                    j = len - 1;
                    for (; a[j] <= a[i]; --j) ;
                    int p = a[j];
                    a[j] = a[i];
                    a[i] = p;
                    j = i + 1;
                    for (int ed = len - 1; j < ed; --ed) {
                        p = a[ed];
                        a[ed] = a[j];
                        a[j++] = p;
                    }
                    return true;
                }
            }
            return false;
        }


        static long mul(long a, long b, long p) {
            long res = 0, base = a;

            while (b > 0) {
                if ((b & 1L) > 0)
                    res = (res + base) % p;

                base = (base + base) % p;
                b >>= 1;
            }

            return res;
        }

        static long mod_pow(long k, long n, long p) {
            long res = 1L;
            long temp = k % p;

            while (n != 0L) {
                if ((n & 1L) == 1L) {
                    res = mul(res, temp, p);
                }

                temp = mul(temp, temp, p);
                n = n >> 1L;
            }

            return res % p;
        }


        public static double roundD(double result, int scale) {
            BigDecimal bg = new BigDecimal(result).setScale(scale, RoundingMode.UP);
            return bg.doubleValue();
        }


    }

    private static void solve() {
        InputStream inputStream = System.in;
//                InputStream inputStream  = null;
//                try {
//                    inputStream = new FileInputStream(new File("D:\\chrome_download\\exp.out"));
//                } catch (FileNotFoundException e) {
//                    e.printStackTrace();
//                }
        OutputStream outputStream = System.out;
//                OutputStream outputStream = null;
//                File f = new File("D:\\chrome_download\\");
//                try {
//                    f.createNewFile();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//                try {
//                    outputStream = new FileOutputStream(f);
//                } catch (FileNotFoundException e) {
//                    e.printStackTrace();
//                }
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task task = new Task();
        task.solve(1, in, out);
        out.flush();
        out.close();
    }

    public static void main(String[] args) {
        new Thread(null, () -> solve(), "1", (1 << 30)).start();
        //  solve();
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String nextLine() {
            String line = null;

            try {
                line = reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return line;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public char nextChar() {
            return next().charAt(0);
        }

        public int[] nextArray(int n) {
            int res[] = new int[n];

            for (int i = 0; i < n; ++i) {
                res[i] = nextInt();
            }

            return res;
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }


    }
}

C++11(clang++ 3.9) 解法, 执行用时: 74ms, 内存消耗: 5372K, 提交时间: 2020-08-04 16:22:39

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 50002
#define M 10002
using namespace std;
int n,c,i,j,s,e,a,b,f[M][1<<6],g[M][1<<6],ans;
int main(){
	cin>>n>>c;
	for(i=1;i<=c;i++){
		int x,tmp1=0,tmp2=0;
		cin>>e>>a>>b;
		for(j=1;j<=a;j++){
			cin>>x;
			tmp1|=(1<<(4-(x-e+n)%n));
		}
		for(j=1;j<=b;j++){
			cin>>x;
			tmp2|=(1<<(4-(x-e+n)%n));
		}
		for(j=0;j<(1<<5);j++){
			if((j&tmp1)||(j&tmp2)!=tmp2) g[e][j]++;
		}
	}
	for(s=0;s<(1<<4);s++){
		memset(f[0],0xcf,sizeof(f[0]));
		f[0][s]=0;
		for(i=1;i<=n;i++){
			for(j=0;j<(1<<5);j++){
				f[i][j]=max(f[i-1][j>>1],f[i-1][(j>>1)+(1<<4)])+g[i][j];
			}
		}
		ans=max(ans,max(f[n][s],f[n][s+(1<<4)]));
	}
	cout<<ans<<endl;
	return 0;
}

上一题