Educational Codeforces Round 161 (Rated for Div. 2) --- E. Increasing Subsequences -- 题解

目录

E. Increasing Subsequences

题目描述:

思路解析:

代码实现:

方案1:会超数组长度200的限制 

方案2:可行答案:


E. Increasing Subsequences

题目描述:

        Educational Codeforces Round 161 (Rated for Div. 2) --- E. Increasing Subsequences -- 题解_第1张图片

思路解析:

        看到数据范围 2 - 1e18,首先想到一般方法无法解决,肯定要往二进制方法方面靠。

        然后想到二进制后,开始找规律,可以发现 :

       1位递增串可以解决2个递增序列,

       2位递增串可以解决4个递增序列,

      3位递增串可以解决8个递增序列,符合二进制,那么其中包含的递增序列都重复的包含了空串这个递增序列,那么其实1位可以解决一个递增序列,2位可以解决三个递增序列,3位可以解决七个递增序列。其实也可以暗含的转为二进制(都多余的加一位)。

        这种方法可行,但是因为题目要求数组长度只能为 [1,200],那么这个方法会超数组范围,因为我们是根据二进制位一位一位解决的,每位之间的信息没有关联起来。假如我们解决1101(二进制)这个数字,我们是单独的处理这四位,这四位之间没有联系。  

        1101(二进制) --- 答案1: 4 5 3 0 1 2 -1  答案2: 1 -1 2 3 -2

        那如何让每位联系起来,来节省空间,观察 4 5 3这个序列可以发现,当序列为4,可以解决两个递增序列,当序列为4 5,可以解决4个递增序列,当序列为 4 5 3可以解决五个递增序列。

        从中又可以发现,如果当一个序列 X,可以解决Y个递增序列,序列X的最大值为max,最小值为min,那么 序列F={X, max + 1}可以解决2*Y个递增序列,那么G={X, min-1}可以解决Y+1个递增序列。此时又用到了每位之间的关联,又体现了二进制,问题解决。

代码实现:

方案1:会超数组长度200的限制 

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        for (int o = 0; o < t; o++) {
            long x = input.nextLong();
            x -= 1;
            int p = 1;
            int max = 1000;
            int[] res = new int[2500];
            int size = 0;
            while (x > 0){
                if ((x & 1) == 1){
                    int m = size + p - 2;
                    size = size + p - 1;
                    for (int i = 0; i < p - 1; i++) {
                        res[m--] = max--;
                    }
                    res[size++] = max--;
                }
                p++;
                x >>= 1;
            }
            System.out.println(size);
            for (int i = 0; i < size; i++) {
                System.out.print(res[i] + " ");
            }
            System.out.println();
        }
    }



}

方案2:可行答案:

import java.io.*;
import java.util.*;

public class Main {
    static int size = 0;
    static int mx = 0;
    static int my = 0;
    static int[] res;
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        for (int o = 0; o < t; o++) {
            long x = input.nextLong();
            mx = 0;
            size = 0;
            my = 0;
            res = new int[2500];
            dfs(x);
            System.out.println(size);
            for (int i = 0; i < size; i++) {
                System.out.print(res[i] + " ");
            }
            System.out.println();
        }
    }

    public static void dfs(long x) {
        if (x == 1) return;
        if (x % 2 == 1){
            dfs(x - 1);
            res[size++] = --mx;
        }else {
            dfs(x >> 1);
            res[size++] = ++my;
        }
    }

}

                  

你可能感兴趣的:(算法)