本图片引用自https://www.cnblogs.com/shenben/p/10380671.html
import java.util.Arrays;
import java.util.Scanner;
class Stick{
int len; // 木棍的长度
boolean mark; //标记这根木棍是否被用过;
Stick(int len,boolean mark){
this.len = len;this.mark = mark;
}
}
public class C1455 {//最小值min的范围肯定是在最长木棍长度~sum之间
static int length,n,sum,count;//count表示sum除以length
static Stick[]all;
static boolean flag;
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
while(scan.hasNext()) {
n = scan.nextInt();all = new Stick[n];sum=0;
for(int i=0;i<n;i++) {
Stick stick = new Stick(scan.nextInt(),false);
all[i] = stick;
sum+=all[i].len;
}//读取完成
Arrays.sort(all);//从小到大
for(int k=all[n-1].len;k<=sum;k++) {//k表示找出的最短木棍长
if(sum%k!=0) {
continue;//需要sum能整出木棍长度的
}else {
count = sum/k;
dfs();
if(flag) break;
}
}
}
}
//len为一模一样的木棒的长度,num统计当前用过的长度(length)木棒的数量,pos标记数组的每一个元素 l表示这个木棒上已经拼接的长度
boolean dfs(int len,int num,int l,int pos){
if(len==sum) return true; //递归出口
if(num==count) return true;
for(int i=n-1;i>=pos;i--){
if(all[i].mark)continue; //如果木棍被标记过,跳过去
if(len==(all[i].len+l)){//如果一模一样的木棒的长度等于已经拼接的+这个木棒
all[i].mark=true;//用上
if(dfs(len,num+1,0,0)) return true;//用完一个木棒了,用下一个
all[i].mark=false;
return false;
}
else if(len>(all[i].len+l)){
all[i].mark=true;
l+=all[i].len;
if(dfs(len,num,l,i-1))
return true;
l-=all[i].len; //如果不能拼接,那么就恢复
all[i].mark=false;
if(l==0) return false;//如果更小的也拼不了,那么整体就不能拼
while(all[i].len==all[i-1].len)i--; //如果两个长度相等,就直接找下一个段长度
}
}
return false;
}
}