问题描述
有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最小。
输入格式
第一行两个整数N,M。
一行N个整数,表示木棍的长度。
输出格式
一行一个整数,表示最小的差距
样例输入
3 2
10 20 40
样例输出
10
数据规模与约定
N , M ≤ 7 N,M \le 7 N,M≤7
解题思路
题目说把 N N N 根木棍,通过合并木棍将其变成 M M M 根木棍,然后给出的数据范围很小(没超过10),我们就可以通过 d f s dfs dfs 暴力搜索出每一种情况,找出答案即可。
题解代码
import java.io.*;
import java.util.*;
public class Main{
static int ans = Integer.MAX_VALUE;
static void dfs(int[] a, int n, int m, int cnt, boolean[] st) {
if (n-cnt < m) return;//如果木棍数目小于M了,递归终止
if (n-cnt == m) {//木棍数刚好等于M,计算当前这种情况的差值
int max = 0, min = Integer.MAX_VALUE;
for (int i = 0; i < n; i ++ ) {
if (!st[i]) {
if (a[i] > max) max = a[i];
if (a[i] < min) min = a[i];
}
}
// System.out.println(max + " " + min);
ans = Math.min(ans, max-min);
return;
}
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < n; j ++ ) {
if (i != j && !st[i] && !st[j]) {//不能和自己合并且没有被合并过
a[i] += a[j];//将第j根木棍粘到第i根木棍后
st[j] = true;
dfs(a, n, m, cnt+1, st);
a[i] -= a[j];//恢复现场
st[j] = false;
}
}
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] a = new int[10];
boolean[] st = new boolean[10];
for (int i = 0; i < n; i ++ ) {
a[i] = sc.nextInt();
}
dfs(a,n,m, 0, st);//cnt是记录被合并的木棍数量,st表示木棍是否被合并
System.out.println(ans);
}
}