题目描述
给定一个数组nums,将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,组内元素和的最小值。
输入描述
第一行输入m
接着输入m个数,表示此数组nums数据范围:1<=m<=50,1<=nums[i]<=50
输出描述
最小拆分数组和
用例
输入
7
4 3 2 3 5 2 1
输出
5
说明
可以等分的情况有:
4个子集(5) ,(1,4) ,(2,3),(2,3)
2个子集(5,1,4) , (2,3,2,3)但最小的为5。
个人解法
不保证通过率
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
*
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(br.readLine());
String[] input = br.readLine().split(" ");
int[] nums = new int[count];
int sum = 0;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < count; i++) {
nums[i] = Integer.parseInt(input[i]);
sum += nums[i];
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
for (int i = count; i > 0; i--) {
if (cancan(nums, sum, i)) {
System.out.println(sum / i);
break;
}
}
}
public static boolean can(int[] nums, int k, int all) {
if (all % k > 0) {
return false;
}
int per = all / k;
Arrays.sort(nums);
if (nums[nums.length - 1] > per) {
return false;
}
int n = nums.length;
boolean[] dp = new boolean[1 << n];
int[] curSum = new int[1 << n];
dp[0] = true;
for (int i = 0; i < 1 << n; i++) {
if (!dp[i]) {
continue;
}
for (int j = 0; j < n; j++) {
if (curSum[i] + nums[j] > per) {
break;
}
if (((i >> j) & 1) == 0) {
int next = i | (1 << j);
if (!dp[next]) {
curSum[next] = (curSum[i] + nums[j]) % per;
dp[next] = true;
}
}
}
}
return dp[(1 << n) - 1];
}
public static boolean cancan(int[] nums, int sum, int k) {
if (sum % k > 0) return false;
int average = sum / k;
Arrays.sort(nums);
int count = nums.length;
if (nums[count - 1] > average) return false;
boolean[] dp = new boolean[1 << count];
dp[0] = true;
int[] temp = new int[1 << count];
for (int i = 0; i < 1 << count; i++) {
if (!dp[i]) continue;
for (int j = 0; j < count; j++) {
if (temp[i] + nums[j] > average) break;
//j未被使用
if ((i >> j & 1) == 0) {
int next = i | 1 << j;
if (!dp[next]){
temp[next] = (temp[i] + nums[j]) % average;
dp[next] = true;
}
}
}
}
return dp[(1 << count) - 1];
}
}