第一讲、整数划分(回溯实现)

来源:互联网 发布:宾馆软件破解版 编辑:程序博客网 时间:2024/06/06 01:17
/**
 * 
 * @author chenzhuzuo
 * 回溯法解决数字拆分问题
 * 问题描述:
 * 整数的分划问题。 
如,对于正整数n=6,可以分划为: 

5+1 
4+2, 4+1+1 
3+3, 3+2+1, 3+1+1+1 
2+2+2, 2+2+1+1, 2+1+1+1+1 
1+1+1+1+1+1+1 
现在的问题是,对于给定的正整数n,编写算法打印所有划分。
用户从键盘输入 n (范围1~10)
程序输出该整数的所有划分。
 *
 *
 *以前做这个题时一直找不到好的思路,在网上也看了一下别人的做法,更多的是使用递归的算法,
 *看了还是不太明白,这几天研究了一下回溯算法,做了几个比较经典的题目,感觉本题可以用求
 *子集和的思路来解决,就试了一下,最后还是做出来了,不过效率不是很高。经过今天的学习
 *,感觉回溯法确实很难懂,但是一旦你弄懂了,回溯法可以说是万能的,真的很好用
 */
public class ShuziChaiFei {


/**
* @param args
*/
public static void main(String[] args) {
printResult(6);
}
/**

* @param n对n进行拆分
*/
private static void printResult(int n){
int a[]= new int[n+1];//用于记录每个数出现的个数(1=<i<=n);
for(int i=0;i<=n;i++){
a[i]=0;
}
int sum=0;
int k = 1;
while(k>=1){
a[k] += 1;
sum+=k;
if(sum==n){//如果当前的和等于n则获得一个解,输出
for(int i=1;i<=k;i++){
int m=1;
//a[i]等值表示i在这个解中出现的次数
while(m<=a[i]){
if(m==a[i]&&i==k){
System.out.print(i);
   m++;

   }
   else{
    System.out.print(i+"+");
m++;
   
   }
}
}
a[k]++;//继续搜索解空间
sum+=k;
System.out.println();
}
else if(sum>n){
sum -= k;
a[k] -=1;
k++;
}
//当k>n时进行回溯
if(k>n){
k--;
while(a[k]>0){
sum=sum-a[k]*k;
k--;
}
while(a[k]==0){
k--;
if(k<1){
return;
}
}
sum -= k;
a[k]--;
k++;

}
}
}


}
0 0
原创粉丝点击