NC50527. 动物园
描述
输入描述
输入的第一行包含两个整数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; }