-
题目描述:
-
一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
{3,3}{2,4}{6} m=3 所以m的最大值为3。
-
输入:
-
存在多组数据,每组数据一定行为一个正整数n(n<=64),第二行为n个数字。当n为0时,测试结束。
-
输出:
-
输出最大值m。
-
样例输入:
-
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
-
样例输出:
-
4 2
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
class Main
{
public static final boolean DEBUG = false;
public static int N = 100;
public BufferedReader cin;
public PrintWriter cout;
public StreamTokenizer tokenizer;
public int[] numArr;
public int n, sum;
public boolean[] vis;
public void init()
{
try {
if (DEBUG) {
cin = new BufferedReader(new InputStreamReader(
new FileInputStream("d:\\OJ\\uva_in.txt")));
} else {
cin = new BufferedReader(new InputStreamReader(System.in));
}
cout = new PrintWriter(new OutputStreamWriter(System.out));
tokenizer = new StreamTokenizer(cin);
} catch (Exception e) {
e.printStackTrace();
}
}
public String next()
{
try {
tokenizer.nextToken();
if (tokenizer.ttype == StreamTokenizer.TT_EOF)
return null;
else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
return String.valueOf((int) tokenizer.nval);
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean input()
{
String s = next();
if (s == null) return false;
n = Integer.parseInt(s);
if (n == 0) return false;
numArr = new int[n];
vis = new boolean[n];
sum = 0;
for (int i = 0; i < n; i++) {
numArr[i] = Integer.parseInt(next());
sum += numArr[i];
}
return true;
}
public boolean Try(int m)
{
if (sum % m != 0) return false;
Arrays.fill(vis, false);
return dfs(sum / m, m, m, 0);
}
public boolean dfs(int cnt, int max, int re, int s)
{
if (cnt == 0) return true;
if (re == 0) {
//找到一个组合的值为max
return dfs(cnt - 1, max, max, 0);
}
for (int i = s; i < n; i++) {
if (vis[i] || re - numArr[i] < 0) continue;
vis[i] = true;
if (dfs(cnt, max, re - numArr[i], i + 1)) return true;
vis[i] = false;
//剪枝在找到一个组合的值为max后,接下来的不能成立
if (re - numArr[i] == 0) break;
//剪枝在无法找到构成max
if (max == re) break;
//剪枝在未选择时,跳过相同的
while (i + 1 < n && numArr[i + 1] == numArr[i]) i++;
}
return false;
}
public void solve()
{
Arrays.sort(numArr);
for (int start = 0, end = numArr.length - 1; start < end; start++, end--) {
int tmp = numArr[start];
numArr[start] = numArr[end];
numArr[end] = tmp;
}
int m = numArr[0];
while (!Try(m)) m++;
cout.println(sum / m);
cout.flush();
}
public static void main(String[] args)
{
Main solver = new Main();
solver.init();
while (solver.input()) {
solver.solve();
}
}
}