目录
题目描述
输入描述
输出描述
用例
题目解析
算法源码
给定一个数组nums,可以将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,最大的平分组个数。
第一行输入 m
接着输入m个数,表示此数组
数据范围:1<=M<=50, 1<=nums[i]<=50
最大的平分组数个数
输入 | 7 4 3 2 3 5 2 1 |
输出 | 4 |
说明 | 可以等分的情况有: 4 个子集(5),(1,4),(2,3),(2,3) 2 个子集(5, 1, 4),(2,3, 2,3) 最大的平分组数个数为4个。 |
输入 | 7 5 2 1 5 2 1 5 2 1 |
输出 | 4 |
说明 | 可以等分的情况有: 4 个子集(5,1),(5,1),(5,1),(2,2,2) 2 个子集(5, 1, 5,1),(2,2, 2,5,1) 最大的平分组数个数为4个。 |
本题和
华为机试 - 叠积木_伏城之外的博客-CSDN博客_叠积木 算法
华为机试 - 等和子数组最小和_伏城之外的博客-CSDN博客
属于类似,解题步骤基本相同。
题解请看叠积木。
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});const lines = [];
rl.on("line", (line) => {lines.push(line);if (lines.length === 2) {const m = lines[0] - 0;const arr = lines[1].split(" ").map(Number);console.log(getResutlt(m, arr));lines.length = 0;}
});function getResutlt(m, arr) {const sum = arr.sort((a, b) => b - a).reduce((p, c) => p + c);let maxCount = m;while (maxCount >= 1) {if (canPartition(arr, sum, maxCount)) {return maxCount;} else {maxCount--;}}
}function canPartition(arr, sum, maxCount) {if (sum % maxCount) return false;const subSum = sum / maxCount;if (subSum < arr[0]) return false;while (arr[0] === subSum) {arr.shift();maxCount--;}const buckets = new Array(maxCount).fill(0);return partition(0, arr, subSum, buckets);
}function partition(start, arr, subSum, buckets) {if (start === arr.length) return true;const select = arr[start];for (let i = 0; i < buckets.length; i++) {if (i > 0 && buckets[i] === buckets[i - 1]) continue;if (buckets[i] + select <= subSum) {buckets[i] += select;if (partition(start + 1, arr, subSum, buckets)) return true;buckets[i] -= select;}}return false;
}