| Language:Default Jury Compromise
Description In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the general public. Every time a trial is set to begin, a jury has to be selected, which is done as follows. First, several people are drawn randomly from the public. For each person in this pool, defence and prosecution assign a grade from 0 to 20 indicating their preference for this person. 0 means total dislike, 20 on the other hand means that this person is considered ideally suited for the jury. Input The input file contains several jury selection rounds. Each round starts with a line containing two integers n and m. n is the number of candidates and m the number of jury members. Output For each round output a line containing the number of the jury selection round ('Jury #1', 'Jury #2', etc.). Sample Input 4 2 1 2 2 3 4 1 6 2 0 0 Sample Output Jury #1 Best jury has value 6 for prosecution and value 4 for defence: 2 3 import java.util.Scanner;
public class Main {
static short[] p, d;
static short[][][] arr, path;//第一维记录前i组数,第二个记录取几组数据,第三个记录最小差值
static int add, a, b, st, ed;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int cnt = 0;
while (true) {
cnt++;
a = in.nextInt();
b = in.nextInt();
if (a == 0 && b == 0) break;
System.out.println("Jury #" + cnt);
p = new short[a + 1];
d = new short[a + 1];
for (int i = 1; i <= a; i++) {//输入2-n行数据
p[i] = in.nextShort();
d[i] = in.nextShort();
}
dp();
for (int k = 0; k <= add; k++) {//从最小差值开始寻找
if (arr[a][b][add + k] > arr[a][b][add - k]) {//k>0 该式子相当于绝对值相等
System.out.println("Best jury has value " + ((arr[a][b][add + k] + k) / 2) + " for prosecution and value " + ((arr[a][b][add + k] - k) / 2) + " for defence:");
//k值代表a-b+c-d....;
print(a, b, k);
break;
} else if (arr[a][b][add - k] != -1) {
System.out.println("Best jury has value " + ((arr[a][b][add - k] - k) / 2) + " for prosecution and value " + ((arr[a][b][add - k] + k) / 2) + " for defence:");
//k值代表b-a+c-d........;
print(a, b, -k);
break;
}
}
System.out.println();
System.out.println();
}
}
static void dp() {
arr = new short[a + 1][b + 1][40 * b + 30];
path = new short[a + 1][b + 1][40 * b + 30];
add = 20 * b;
st = -b * 20;
ed = -st;
for (int i = 0; i <= a; i++)
for (int j = 0; j <= b; j++)
for (int k = st; k <= ed; k++)
arr[i][j][k + add] = -1;//初始化
arr[0][0][add] = 0;
for (int i = 1; i <= a; i++)
for (int j = 0; j <= b; j++)
for (int k = st; k <= ed; k++)//k值取各个有可能的整数
{
arr[i][j][k + add] = arr[i - 1][j][k + add];//前i-1个选j个,此时k为前i-1个元素取j个的差值
path[i][j][k + add] = 1;//初始化path
if (j > 0 &&
k - p[i] + d[i] >= -add &&
k - p[i] + d[i] <= add &&//这两个条件判断数据在范围内
arr[i - 1][j - 1][k - p[i] + d[i] + add] != -1 &&//k为差值。k - p[i] + d[i]为前一个元素差值
arr[i - 1][j - 1][k - p[i] + d[i] + add] + p[i] + d[i] > arr[i][j][k + add])//总值更大,则替换
{
//此处k为多个数据的差值的绝对值
arr[i][j][k + add] = (short) (arr[i - 1][j - 1][k-p[i]+d[i]+add] + p[i] + d[i]);//k-p[i]+d[i]+add为前面的差值和
//记录summax 差值为k时对应的最大值 第一次为前一组选一组差值为k时,对应的最大值。
//负值存在左边,正值存在右边
path[i][j][k + add] = 2;//path记录第i组选j个数据 数据差值为k时 为2的时候说明这个数据参与了运算
}
}
}
static void print(int i, int j, int k) {//打印最后一行输出结果
if (i == 0 && j == 0 && k == 0)
return;
if (path[i][j][k + add] == 1)
print(i - 1, j, k);
else {
print(i - 1, j - 1, k - p[i] + d[i]);
System.out.print(" " + i);
}
}
} | ||||||||||



