问题描述
HJQ同学发现了一道数学题,要求n拆分成若干自然数和的方案
输入格式
输入n
输出格式
输出n拆分成若干自然数和的方案,每个方案一行
数据规模和约定
n <= 10
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
LinkedList<Integer> track = new LinkedList<>();
int n = scanner.nextInt();
dfs(1, track, n);
}
public static void dfs(int start,LinkedList<Integer> track,int target)
{
if(getsum(track)==target)
{
for(int i=0;i<track.size();i++)
{
if(i==track.size()-1)
{
System.out.print(track.get(i));
}else {
System.out.print(track.get(i)+"+");
}
}
System.out.println();
return;
}
if(getsum(track)>target)
{
return;
}
for(int i=start; i<target;i++)
{
//关键在于i=start这个操作,可以保证下一层遍历的数都是大于等于上一个节点
//这就能够使得数字相同但顺序不同的方案不会发生
track.add(i);
dfs(i, track, target);
track.removeLast();
}
}
public static int getsum(LinkedList<Integer> list)
{
int sum = 0;
for(Integer x:list)
{
sum+=x;
}
return sum;
}
}
核心思想
组合问题,并且所含元素可以重复,元素顺序不同的方案也会被视作同一方案。采用的方法仍然是深度搜索,但会给一个起始下标start,下一层遍历的时候从采用当前元素及后面的元素来进行搜索。