POJ1416--DFS入门
2016-04-25 22:10
323 查看
题目:
现在你要研发一种新型的碎纸机,待粉碎的纸上面有一串数字,要求把纸粉碎成的几片上的数字的和尽量接近而不能超过给定的数字target number。比如:一片纸上的数字为12346,target number为50,那么就可以把纸粉碎为1、2、34、6,其加和为43,是所有粉碎方法中最接近50而不超过50的最优解。分析:这种是一个基本的DFS题目,用来入门是相当不错的.
题目换句话来理解就是有一串数字中间用+号来连接,使其结果小于或等于指定值的最优解.
EG:
总量50 对应字串12346
那么可以分为以下几种情况
50 1+2+3+4+6=16
50 12+3+4+6=25
50 123+4+6=133
50 1+23+4+6=34
等等…
那么我们就可以挨个试,也就是暴力搜索的方法,当然也要剪枝来提高效率.先看看基本的递归图
“”表示剩余字串,也就是下一步要递归的字串
跟着图的思路,那么代码就很容易写出来了,这里只写了一个样例程序,具体输入输出格式可以自己改写
public class Main { static int sumTotal = 50;//规定最大值 static String num = "12346";//规定字串 static int max = 0;//得到最大值结果 static boolean isCheck = true;//当前最大值结果是否唯一 static StringBuilder builder = new StringBuilder();//当前最大值结果对应的方式 public static void main(String[] args) { DFS(num, 0); } private static void DFS(String num,int curSum){ //递归结束条件 if (num == null || "".equals(num)) { if (curSum == max) { isCheck = false; System.err.println(builder.toString()+"---max = "+max+"---check:"+isCheck); return ; }else if (curSum > max) { max = curSum; isCheck = true; //记录结果,打印 System.err.println(builder.toString()+"---max = "+max+"---check:"+isCheck); builder.delete(0, builder.length()); return ; } } //这里是循环的主体 for (int i = 0; i < num.length(); i++) { int startNum = Integer.parseInt(num.substring(0,i+1)); //剪枝,当总和大于total就没必要往后递归了 if ((curSum + startNum)>sumTotal) { return; } //暂存结果,回溯的时候赋值给builder StringBuilder temp = new StringBuilder(builder); builder.append(startNum).append(" "); //下一步递归 DFS(num.substring(i+1),curSum+startNum); builder = temp; } } }
结果很容易得出
相关文章推荐
- Libgdx 之Actor 演员类
- 构建之法阅读笔记04
- 编译原理:C语言词法分析器
- Kubernetes之kubectl常用命令
- 系统架构三要素
- 一个内存数据交换的例子(一)
- python中实现有序字典
- HBASE大表的集群原理
- Socket
- linux高级命令
- phpStudy升级MySQL教程
- composer使用
- 【图-最短路】NOIP2009最优贸易
- RxJS入门(1)---Observer 和 Iterator模式简介
- android图片加载导致的OOM分析及有效解决办法(BitmapUtils)
- 常见面试之机器学习算法思想简单梳理
- java基础(25)--java annotation详解
- I帧,P帧,B帧简介
- 内核级线程
- leetcode-202. Happy Number