Bootstrap

文具信息管理系统java,第15章 搜索枚举

1、文具店

算法分析

暴力枚举每种情况,dfs(u,cnt)表示从第0个位置开始枚举,当前选第0个,当 cnt == k 且 u == n时,表示已经枚举完了所有位置且已经够k个,则更新ans

当枚举到第u个位置,准备枚举第cnt个数的时候,若后面的总元素小于剩下需要的个数时,则剪枝

时间复杂度

math?formula=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

算法分析

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

时间复杂度

math?formula=O(2%5En)

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则输出,大于n则break

dfs(u,x,num):u表示枚举第u个数,x表示从x开始往后枚举,num表示当前已经枚举的数的总和

时间复杂度

math?formula=O(n%20*%20n!)

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

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

时间复杂度

math?formula=O(2%20%5E%20n)

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);

}

}

;