整数划分 深搜(递归)
来源:互联网 发布:plc编程线 编辑:程序博客网 时间:2024/06/16 18:36
java
几个简单的问题,运用深搜(递归)解决
1. N个整数划分为K个子集
2. 在N个整数中选取M个数,使其和等指定值
3. 在N个整数中选取任意个数,使其和等于指定值
4. 在N个整数集合中,将集合划分为两部分,且子集交集为空,使其子集的和尽量相等
import java.util.Arrays;import com.util.Array;import com.util.Print;/***2017年12月20日 下午12:44:22<br>*TODO:<pre><br> * </pre> Question:<pre><br> </pre> Analysis:<pre><br> </pre>*/public class 整数划分{ public static void main(String[] args) { // s1_test(); // s2_test(); // s3_test(); s4_test(); } public static void s1_test() { int i = -1; int n = 10; while(++i<=n+1) { System.out.println(n+" "+i+" "+number_split1(n,i)); } } /** * TODO:<pre> * N个整数划分为K个子集,每个子集不为空且两两交集为空 *求,有多少种划分方法 *考虑一个子集i,如果i单独构成一个子集,那么分法 c(n-1,k-1) *如果i不单独构成一个子集,那么k*c(n-1,k) *边界条件: *( n==k||(n>0&&k==1) ) return 1; *( n<k||(n>0&&k==0) ) return 0; * @param n * @param k */ public static int number_split1(int n,int k) { if( n==k||(n>0&&k==1) ) return 1; if( n<k||(n>0&&k==0) ) return 0; int sum = 0; sum = number_split1(n-1,k-1)+k*number_split1(n-1,k); return sum; } static int arr[]; static int ans[]; static int tot; public static void s2_test() { int len = 20,sum = 30,k = 5; arr = Array.getRandomIntArrayNoRepeat(1,22,len); ans = new int[k+1]; Arrays.sort(arr); tot = 0; Print.printArray(arr); number_split2(sum,k,len-1); System.out.println(tot); } /** * TODO:<pre>整数划分2 * 在N个整数中选取M个数,使其和等指定值 * 分析: * 1.递归 * 先排序,然后对于元素i,我们考虑选取它 * 然后方程变为d(sum-i,m-1) * 不选取:d(sum,m-1) * 边界: * sum==0&&m==0 return true * sum<0||m<0,index<0 ||arr[index]>sum return false * @param sum 当前的数字和 * @param k 选取K个整数 * @param index 数组下标 */ public static void number_split2(int sum,int m,int index) { if( sum==0&&m==0 ) { tot++; Print.printArray(ans,1,ans.length-1); return; } if( sum<0||m<0||index<0||arr[index]>sum ) return; ans[m] = arr[index]; number_split2(sum-arr[index],m-1,index-1); ans[m] = 0; number_split2(sum,m,index-1); } public static void s3_test() { int len = 20,sum = 30; arr = Array.getRandomIntArrayNoRepeat(1,22,len); ans = new int[len]; Arrays.sort(arr); tot = 0; Print.printArray(arr); number_split3(sum,0,len-1); System.out.println(tot); } /** * TODO:<pre> * 整数划分3 * 在N个整数中选取任意个数,使其和等于指定值 * @param sum 和 * @param counter 选中的数字个数 * @param index 数组当前下标 */ public static void number_split3(int sum,int counter,int index) { if( sum==0 ) { tot++; Print.printArray(ans,0,counter-1); return; } if( sum<0||index<0||arr[index]>sum ) return; ans[counter] = arr[index]; number_split3(sum-arr[index],counter+1,index-1); ans[counter] = 0; number_split3(sum,counter,index-1); } static int s4M = 2;// s4 阈值 public static void s4_test() { int len = 10,sum = 0; arr = Array.getRandomIntArrayNoRepeat(1,10,len); ans = new int[len]; Arrays.sort(arr); tot = 0; Print.printArray(arr); for(int i = 0;i<len;i++) { sum += arr[i]; } number_split4(sum/2,0,len-1); System.out.println(tot); } /** * TODO:<pre> * 整数划分4 * 在N个整数集合中,将集合划分为两部分,且子集交集为空,使其子集的和尽量相等 * 如果和的差超过某个阈值,则输出不能完成信息 * 分析: * 与上面的整数划分类似,将数组求和sum;然后number_split3(sum/2,0,len-1), */ public static void number_split4(int sum,int counter,int index) { if( sum==0||Math.abs(sum)<=s4M ) { tot++; ans[counter] = sum;// 记录 sum相差值,数组最后一位就是差值了 Print.printArray(ans,0,counter); } if( index<0 ) return; ans[counter] = arr[index]; number_split4(sum-arr[index],counter+1,index-1); ans[counter] = 0; number_split4(sum,counter,index-1); }}
阅读全文
0 0
- 整数划分 深搜(递归)
- 整数划分(递归)
- 整数划分(递归)
- 整数划分(递归)
- 整数划分(递归)
- 整数划分(递归)
- 整数划分问题(递归)
- 整数划分问题(递归)
- 递归-整数划分(1)
- 整数划分(递归方法)
- 整数划分问题(递归策略)
- 整数拆分(划分)问题 递归
- 整数划分问题(递归法)
- 整数划分定义与解析(递归)
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 递归经典应用(整数的划分)
- Algorithm之路十七:Letter Combinations of a Phone Number
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- docker问题搜集-解决方案
- 近似求π
- Python 中的None以及 == 与 is 的区别,以及判断某个list或者dict元素是否为None
- 整数划分 深搜(递归)
- angularJs
- Java-NIO(六):Channel聚集(gather)写入与分散(scatter)读取
- iOS 极光推送踩过的坑~
- 小米手机 无法monkey测试
- 两种价值观念
- 从零开始用Python构造决策树(附公式、代码)
- 史上超强图像处理开源工具包--ImageMagick
- 项目总结