编程之美
来源:互联网 发布:js input 光标颜色 编辑:程序博客网 时间:2024/06/02 05:18
问题导读:
假设有n块大小不一的烙饼,翻烙饼时只能从最上面的烙饼开始,一次抓住最上面的几块饼,把它们上下颠倒个儿,那么最少要翻多少次,才能够达到最后的大小有序?得到一个解决方案。
解决方案:
package Chapter1;import java.util.*;/* 烙饼排序(寻找最优翻转方案): 1. 将本应该相邻的两个烙饼尽可能的翻转到一起 2. 当前步数 + 估算这次搜索所需要下界步数 < 最多交换次数 */public class Func_1_3_1 { int []cake_arr; //烙饼信息数组 int cake_cnt; // 烙饼个数 int max_swap; //最多交换次数 int []swap_arr; //烙饼交换结果数组 int []reverse_cake_arr; // 当前翻转 烙饼信息数组 int []reverse_cake_swap_arr; //当前翻转 烙饼交换结果数组 int n_search; // 当前搜索次数 public Func_1_3_1(int []cake_arr, int cake_cnt) { this.cake_arr = cake_arr; this.cake_cnt = cake_cnt; this.max_swap = upperBound(cake_cnt); this.swap_arr = new int[this.max_swap + 1]; this.reverse_cake_arr = new int[cake_cnt]; for (int i = 0; i<cake_cnt; i++) { this.reverse_cake_arr[i] = this.cake_arr[i]; } this.reverse_cake_swap_arr = new int[this.max_swap]; this.n_search = 0; } // 得到上界 int upperBound(int cake_cnt) { /* 1. 最大的在倒数第二位,将它翻到第一位 2. 再将最上的(最大的)翻到最后一位 3. 最后,最小的自然在上,不用翻, 4. 2*(n-1) */ return (cake_cnt-1) * 2; } // 得到下界 int lowerBound(int []cake_arr, int cake_cnt) { int flag, ret = 0; for (int i = 1; i < cake_cnt; i++) { flag = cake_arr[i] - cake_arr[i]; if (flag != 1 && flag != -1) { ret++; } } return ret; } // 翻转烙饼 void reverse(int n_begin, int n_end) { if (n_begin > n_end) return; int i, j; for(i = n_begin, j = n_end; i<j; i++, j--) { this.reverse_cake_arr[i] = this.reverse_cake_arr[i] + this.reverse_cake_arr[j] - (this.reverse_cake_arr[j] = this.reverse_cake_arr[i]); } } // 判断是否已经排序完成 boolean isSorted(int []cake_arr, int cake_cnt) { for (int i = 1; i<cake_cnt; i++) { if (cake_arr[i] < cake_arr[i-1]) { // 下面的小于上面的,false return false; } } return true; } // 深搜 // 省空间,不一定是最优解 // 重在剪枝 void dfs(int step) { int n_estimate; this.n_search++; n_estimate = lowerBound(this.reverse_cake_arr, this.cake_cnt); // 步数大于上界 if (step + n_estimate > this.max_swap) return; // 如果排序完成 if (isSorted(this.reverse_cake_arr, this.cake_cnt)) { if (step < this.max_swap) { this.max_swap = step; for (int i = 0; i<this.max_swap; i++) this.swap_arr[i] = this.reverse_cake_swap_arr[i]; } return; } // 递归进行翻转 for (int i = 1; i<cake_cnt; i++) { reverse(0, i); this.reverse_cake_swap_arr[step] = i; dfs(step + 1); reverse(0, i); } } // 输出 void outPut() { System.out.println(); System.out.println(Arrays.toString(this.swap_arr)); System.out.println("搜索次数: " + this.n_search + "\n步数: " + this.max_swap); } public static void main(String []args) { int []arr = {4, 2, 1, 3}; Func_1_3_1 f = new Func_1_3_1(arr, 4); f.dfs(0); f.outPut(); }}
参考博文:
编程之美学习笔记 - 一摞烙饼的排序
dfs(x,y,step)if visitedif okfor:dfs(x,y,step+1)bfs()queue.offerwhile(queue.isNotEmpty):queue.pollif okfor:queue.offer
阅读全文
0 0
- 推荐《编程之美》
- 编程之美 - 序
- 品味《编程之美》
- 编程之美???
- 编程之美
- 编程之美
- 编程之美有感
- 编程之美
- 编程之美摘录
- 编程之美
- 编程之美总结
- 编程之美2.21
- 编程之美
- 编程之美-前言
- 编程之美
- 编程之美1
- 《编程之美》读书笔记
- 编程之美3.1
- POJ 3523 The Morning after Halloween 搜索
- POJ-2255 Tree Recovery
- 10 款下载神器
- Django创建数据表
- populating-next-right-pointers-in-each-node II
- 编程之美
- 优化Oracle数据库,有两种方式
- 剑指offer之跳台阶
- MySQL数据库中SQL语句的基本使用(二)
- 单例模式和工厂模式
- 剑指offer:树的子结构
- 对指定文件夹及其子文件夹下面的某一类格式(.tif)的文件进行重命名
- Spring对jdbc操作的支持
- Python matplotlib 练习题