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);
        }
    }
    
  • 相关阅读:
    jquery的选择器
    css单行文本与多行溢出文本的省略号问题
    div仿textarea使高度自适应
    css3制作炫酷导航栏效果
    变态的iis10
    Session丢失——解决方案
    sqlserver安装遇到的问题——1
    Win SERVER 2008 许可证激活失败,系统重启问题
    sqlserver2008 数据库
    VS2010 不显示 最近使用的项目 解决办法
  • 原文地址:https://www.cnblogs.com/lixyuan/p/13176223.html
Copyright © 2011-2022 走看看