zoukankan      html  css  js  c++  java
  • Java 递归、DFS、剪枝、回溯例题

    上楼梯

    有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。 请实现一个方法,计算小孩有多少种上楼的方式。

    给定一个正整数int n,请返回一个数,代表上楼的方式数。

    保证n小于等于100000。
    【代码】

          public static int n;
    	public static void main(String[] args) {
    		Scanner scan = new Scanner(System.in);
    		n = scan.nextInt();
    		System.out.println(fun(0));
    	}
    
    	// 1 2 3
    	public static int fun(int sum) {
    		if (n == sum) {
    			return 1;
    		}
    		if (sum > n) {
    			return 0;
    		}
    		return fun(sum + 1) + fun(sum + 2) + fun(sum + 3);
    	}
    

    机器人走方格

    有一个XxY的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。 请设计一个算法,计算机器人有多少种走法。

    给定两个正整数int x,int y,请返回机器人的走法数目。

    保证x+y小于等于12。
    【代码】

    public static int ans;
    	public static int x,y;
    	public static void main(String[] args) {
    		Scanner scan = new Scanner(System.in);
    		x = scan.nextInt();
    		y = scan.nextInt();
    		f(1,1);
    		System.out.println(ans);
    	}
    	public static void f(int i,int j) {
    		if(i==x&&j==y) {
    			ans++;
    			return;
    		}
    		if(i==x+1||j==y+1) {
    			return;
    		}
    		f(i+1,j); // 往下走
    		f(i,j+1); // 往右走
    		
    	}
    

    硬币表示

    假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},用这些硬币组合够成一个给定的数值n。 例如n=200,那么一种可能的组合方式为 200 = 3 1 + 1*2 + 1*5 + 2*20 + 1 50 + 1 * 100. 问总共有多少种可能的组合方式?

          static int money[] = { 1, 2, 5, 10, 20, 50, 100, 200 };
    
    	public static void main(String[] args) {
    		Scanner scan = new Scanner(System.in);
    		int n = scan.nextInt();
    		System.out.println(combine(n, 7));
    	}
    
    	public static int combine(int n, int k) {
    		if (n < 0) {
    			return 0;
    		}
    		if (n == 0) {
    			return 1;
    		}
    		int cut = 0;
    		for (int i = 0; k >= 0 && i * money[k] <= n; i++) {
    			cut = cut + combine(n - i * money[k], k - 1);
    		}
    		return cut;
    
    	}
    

    剪格子 dfs剪枝回溯

    【问题描述】
    如图p1.jpg所示,3 x 3 的格子中填写了一些整数。
    我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。
    本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
    如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
    如果无法分割,则输出 0
    程序输入输出格式要求:
    程序先读入两个整数 m n 用空格分割 (m,n<10)
    表示表格的宽度和高度
    接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000
    程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。

    例如:
    用户输入:
    3 3
    10 1 52
    20 30 1
    1 2 3

    则程序输出:
    3

    再例如:
    用户输入:
    4 3
    1 1 1 1
    1 30 80 2
    1 1 1 100

    则程序输出:
    10

    (参见p2.jpg)

    资源约定:
    峰值内存消耗(含虚拟机) < 64M
    CPU消耗 < 5000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
    注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
    注意:主类的名字必须是:Main,否则按无效代码处理。
    【代码】

          public static int[][] g,vis;
    	private static int n, m,total;
    	private static int ans = Integer.MAX_VALUE;
    	static void dfs(int i, int j, int steps, int sum) {
    		if (i < 0 || i == n || j < 0 || j == m||vis[i][j]==1) {
    			
    			return;
    		}
    		if(sum==total/2) {
    			ans = Math.min(ans,steps-1);
    			return;
    		}if(sum>total/2) {
    			return;
    		}
    		vis[i][j] = 1;
    		dfs(i - 1, j, steps + 1, sum + g[i][j]); // down
    		dfs(i + 1, j, steps + 1, sum + g[i][j]); // up
    		dfs(i, j - 1, steps + 1, sum + g[i][j]); // left
    		dfs(i, j + 1, steps + 1, sum + g[i][j]); // left
    		vis[i][j] = 0;
    	}
    
    	public static void main(String[] args) {
    		// 试探 —— 解的搜索 1、深搜2、宽搜3、二分搜索
    		// dfs 剪枝 回溯
    		Scanner scan = new Scanner(System.in);
    		m = scan.nextInt();
    		n = scan.nextInt();
    		g = new int[n][m];
    		vis = new int[n][m];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < m; j++) {
    				g[i][j] = scan.nextInt();
    				total = total + g[i][j];
    			}
    		}
    		// =完成输入=
    		dfs(0, 0, 0, 0);
    		System.out.println(ans);
    	}
    
  • 相关阅读:
    简单算法系列之完数的计算
    毕业了
    通过代码实现截取一定字符的实现
    写点做完一个小项目的教训....
    关于ListView下隐藏控件的解决方案
    用C#实现古代诗词的竖排文字
    获得在查询分析器里执行程序的精确时间以及查询效率问题
    要成功必须知道的12个秘诀!
    WAT网站压力测试工具
    wap网站开发相关知识
  • 原文地址:https://www.cnblogs.com/lyhLive/p/13497236.html
Copyright © 2011-2022 走看看