时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
描述
小珂最近收集了些邮票,他想把其中的一些给他的好朋友小明。每张邮票上都有分值,他们想把这些邮票分成两份,并且使这两份邮票的分值和相差最小(就是小珂得到的邮票分值和与小明的差值最小),现在每张邮票的分值已经知道了,他们已经分好了,你知道最后他们得到的邮票分值和相差多少吗?
输入
第一行只有一个整数m(m<=1000),表示测试数据组数。
接下来有一个整数n(n<=1000),表示邮票的张数。
然后有n个整数Vi(Vi<=100),表示第i张邮票的分值。
输出
输出差值,每组输出占一行。
样例输入
2
5
2 6 5 8 9
3
2 1 5
样例输出
0
2
代码
import java.util.Scanner;
/**
* 当成01背包来解,就是把总数分为一半,目的就是往这一半容量的背包里尽可能多地赛东西,塞地越满差值越小(价值和重量一样)同235题
*/
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int number = cin.nextInt();
while (number > 0) {
int n = cin.nextInt();
int sum = 0;
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = cin.nextInt();
sum += arr[i];
}
int[][] help = new int[arr.length + 1][sum / 2 + 1];
for (int i = 1; i <= arr.length; i++) {
for (int j = 1; j <= sum / 2; j++) {
if (j - arr[i - 1] < 0) {
help[i][j] = help[i - 1][j];
} else {
help[i][j] = Math.max(help[i - 1][j], help[i - 1][j - arr[i - 1]] + arr[i - 1]);
}
}
}
System.out.println(sum - 2 * help[arr.length][sum / 2]);
number--;
}
cin.close();
}
}