[CodeForce] Maximum Subsequence

Problem Statement

 

1. N is up to 35, so trying all possible subsequences is too slow (2^35). We can apply the meet in the middle technique and divide A into two equal halves and compute all possible subsequences' sum modulo by M. This takes O(2^17) for each half of A, call the results as S1 and S2.

 

2. Then for each value V in S1, we have 2 options: 1. take V and does not take anything from S2; 2. take V and find the max W in S2 such that V + W <= M - 1. The answer is the max of both options for all V in S1.

3. To speed up the search in option 2, we can either sort S2 then perform binary search or store values of S2 in a sorted set.  

 

    static void solve(int testCnt)
    {
        for (int testNumber = 0; testNumber < testCnt; testNumber++) {
            int n = in.nextInt(), m = in.nextInt();
            int[] a = in.nextIntArrayPrimitive(n);
            if(n == 1) out.println(a[0] % m);
            else {
                int[] x1 = Arrays.copyOfRange(a, 0, n / 2);
                int[] x2 = Arrays.copyOfRange(a, n / 2, n);
                TreeSet<Integer> ts1 = compute(x1, m);
                TreeSet<Integer> ts2 = compute(x2, m);
                int ans = 0;
                for(int v : ts1) {
                    ans = Math.max(ans, v);
                    ans = Math.max(ans, v + ts2.floor(m - 1 - v));
                }
                out.println(ans);
            }
        }
        out.close();
    }
 
    static TreeSet<Integer> compute(int[] x, int m) {
        TreeSet<Integer> ts = new TreeSet<>();
        for(int i = 0; i < (1 << x.length); i++) {
            long sum = 0;
            for(int j = 0; j < x.length; j++) {
                if((i & (1 << j)) != 0) {
                    sum += x[j];
                }
            }
            ts.add((int)(sum % m));
        }
        return ts;
    }

 

posted @ 2022-09-30 10:48  Review->Improve  阅读(26)  评论(0编辑  收藏  举报