美文网首页
第15章 搜索枚举

第15章 搜索枚举

作者: 得力小泡泡 | 来源:发表于2020-04-03 15:42 被阅读0次

1、文具店

算法分析

暴力枚举每种情况,dfs(u,cnt)表示从第0个位置开始枚举,当前选第0个,当 cnt == ku == n时,表示已经枚举完了所有位置且已经够k个,则更新ans
当枚举到第u个位置,准备枚举第cnt个数的时候,若后面的总元素小于剩下需要的个数时,则剪枝

时间复杂度 O(n!)

有剪枝,会比这个复杂度小很多

Java代码

import java.util.Scanner;

public class Main {
    static int n,k;
    static String s;
    static String[] g = new String[10];
    static int ans = Integer.MAX_VALUE;
    static void dfs(int u,int cnt)
    {
        //可行性剪枝
        if(n - u + 1 < k - cnt - 1) return ;
        if(cnt == k && u == n)
        {
            int res = 0;
            for(int i = 0;i < k;i ++) res += Integer.parseInt(g[i]);
            ans = Math.min(ans, res);
            return;
        }
        for(int i = u + 1;i <= n;i ++)
        {
            g[cnt] = s.substring(u,i);
            dfs(i,cnt + 1);
        }
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        s = scan.next();
        n = s.length();
        k = scan.nextInt();
        dfs(0,0);
        System.out.println(ans);
    }
}

2、超级书架2

算法分析

暴力枚举所有奶牛,每个奶牛有选和不选两种情况

时间复杂度 O(2^n)

Java代码

import java.util.Scanner;

public class Main {
    static int N = 25;
    static int n,high;
    static int[] h = new int[N];
    static int ans = Integer.MAX_VALUE;
    static void dfs(int u,int cnt)
    {
        if(u == n)
        {
            if(cnt >= high) ans = Math.min(ans, cnt);
            return;
        }
        //不选
        dfs(u + 1,cnt);
        //选
        dfs(u + 1,cnt + h[u]);
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        high = scan.nextInt();
        for(int i = 0;i < n;i ++) h[i] = scan.nextInt();
        dfs(0,0);
        System.out.println(ans - high);
    }
}

3、自然数拆分

算法分析

依次枚举所有小于n的数,若枚举的数的和等于n则输出,大于nbreak
dfs(u,x,num):u表示枚举第u个数,x表示从x开始往后枚举,num表示当前已经枚举的数的总和

时间复杂度 O(n * n!)

存在剪枝,时间复杂度远小于上面的

Java代码

import java.util.Scanner;

public class Main {
    static int N = 25;
    static int n;
    static int[] a = new int[N];
    static void dfs(int u,int x,int num)
    {
        if(num > n) return;
        if(num == n) 
        {
            System.out.print(n + "=");
            for(int i = 0;i < u;i ++)
            {
                if(i != u - 1) System.out.print(a[i] + "+");
                else System.out.println(a[i]);
            }
            return;
        }
        for(int i = x;i < n;i ++)
        {
            a[u] = i;
            dfs(u + 1,i,num + i);
            
        }
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        dfs(0,1,0);
    }
}

4、狂暴石

算法分析

每块狂暴石有选和不选两种情况,记录当前愤怒值的乘积numa,暴躁值的累加numb,需要对所有情况都不选进行特判即numa == 1 && numb == 0

时间复杂度 O(2 ^ n)

Java代码

import java.util.Scanner;

public class Main {
    static int N = 15;
    static int n;
    static int[] a = new int[N];//愤怒值
    static int[] b = new int[N];//暴躁值
    static long ans = Long.MAX_VALUE;
    static void dfs(int u,int numa,int numb)
    {
        if(u == n)
        {
            if(numa == 1 && numb == 0) return;//可行性剪枝
            ans = Math.min(ans, Math.abs(numa - numb));
            return;
        }
        //不选
        dfs(u + 1,numa,numb);
        //选
        dfs(u + 1,numa * a[u],numb + b[u]);
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        for(int i = 0;i < n;i ++)
        {
            int x = scan.nextInt();
            int y = scan.nextInt();
            a[i] = x;
            b[i] = y;
        }
        dfs(0,1,0);
        System.out.println(ans);
    }
}

相关文章

  • 第15章 搜索枚举

    1、文具店 算法分析 暴力枚举每种情况,dfs(u,cnt)表示从第0个位置开始枚举,当前选第0个,当 cnt =...

  • 回溯算法

    如何理解“回溯算法”? 回溯的处理思想,有点类似枚举搜索。我们枚举所有的解,找到满足期望的解。为了有规律地枚举所有...

  • 回溯算法演练

    什么是回溯算法 回溯算法本质其实就是枚举,在给定的枚举集合中,不断从其中尝试搜索找到问题的解,如果在搜索过程中发现...

  • AcWing 165. 小猫爬山(搜索)

    深度优先搜索(dfs) 体会 要考虑的问题 枚举对象 dfs的参数 返回条件 剪枝技巧原题链接 枚举对象: 车...

  • Swift底层进阶--010:枚举

    C语⾔枚举 先来回顾⼀下C语⾔的枚举写法: ⽐如表示⼀周 7天,⽤C语⾔的枚举写法应该是这样的: 第⼀个枚举成员默...

  • cs106A-MIT-过滤掉了图形部分

    content from MIT-cs106A枚举,接口,搜索算法,标准库课程内容:163

  • 2021-06-26动规相关算法

    回溯算法 概念 类似枚举搜索,枚举所有解,找到满足期望的解。把问题求解的过程分为多个阶段。每个阶段都会面对一个岔路...

  • effective java 第三周

    第6章 枚举和注解 第30条:用 enum 代替 int 常量 在没有 enum 之前表示枚举类型的常用模式时声...

  • 深度优先搜索

    深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法。 使用递归可以很好地实现深度优先搜索。 例题1 有n件...

  • 算法之回溯算法详解

    回溯算法 定义 回溯算法实际上基于DFS(深度优先搜索)的一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问...

网友评论

      本文标题:第15章 搜索枚举

      本文链接:https://www.haomeiwen.com/subject/oyaluhtx.html