zoukankan      html  css  js  c++  java
  • 小易喜欢的数列, 网易笔试题

    动态规划

    f[i][j] 表示数列的长度为i, 并且以数j结尾的合法序列的数量。

    f[i][j] += f[i-1][l], 其中l,j满足合法序列的要求

    //暴力法:时间:O(N*K*K), 空间:O(NK)
    //40%通过
    import java.util.*;
    public class Main {
        static int mod = 1000000007;
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(), k = sc.nextInt();
            int[][] f  = new int[n+1][k+1];
            Arrays.fill(f[1], 1); f[1][0] = 0;
            for(int i=2; i <= n; i++) {
                for(int j=1; j <= k; j++) {
                    for(int l=1; l <= k; l++) {
                        if((l <= j) || (l % j != 0)) {
                            f[i][j] = (f[i][j] + f[i-1][l])  % mod;
                        }
                    }
                }
            }
            //System.out.println(Arrays.deepToString(f));
            int res = 0;
            for(int i=1; i <= k; i++) res = (res + f[n][i]) % mod;
            System.out.println(res);
        }
    }
    

    优化:

    条件为:(l <= j) || (l % j != 0),满足条件的数量明显较多,因此,我们用满足和不满足的和减去不满足的数量,就等于满足条件的数量。取反条件变成为:l % j == 0 && l != j

    取反集以后求f[i][j]枚举的数量从k下降到了k/j。k + k / 2 + k / 3 +...+k/k = k *(1 + 1/2 + ... + 1 /k) 约等于 k * ln(k+1) + 0.5, 因此,问题复杂度从O(K*K) 下降到了O(K*logK)

    // 时间:O(NKlogK)
    import java.util.*;
    public class Main {
        static int mod = 1000000007;
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(), k = sc.nextInt();
            int[][] f  = new int[n+1][k+1];
            Arrays.fill(f[1], 1); f[1][0] = 0;
            
            for(int i=2; i <= n; i++) {
                int sum = 0;
                for(int j=1; j <= k; j++) sum = (sum + f[i-1][j]) % mod;
                for(int j=1; j <= k; j++) {
                    f[i][j] = sum;
                    for(int l=j; l <= k; l = l + j) {
                        if(l!= j) {
                            f[i][j] = (f[i][j] + mod - f[i-1][l])  % mod;
                        }
                    }
                }
            }
            //System.out.println(Arrays.deepToString(f));
            int res = 0;
            for(int i=1; i <= k; i++) res = (res + f[n][i]) % mod;
            System.out.println(res);
        }
    }
    
  • 相关阅读:
    Python操作Excel表格
    Python爬虫实战:爬取美食节川菜信息
    超级实用的Python网络爬虫反反爬策略之构造UA池及IP代理池
    Python 静态方法
    IDEA连接远程服务器Docker部署Spring Boot项目
    Dockerfile 解析
    Python爬虫实战-统计博客园阅读量问题
    Docker 容器数据卷
    Docker镜像
    PL/SQL
  • 原文地址:https://www.cnblogs.com/lixyuan/p/13176223.html
Copyright © 2011-2022 走看看