栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

poj1015动态规划java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

poj1015动态规划java

Language:Default

Jury Compromise

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 39470Accepted: 10695Special Judge

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.
based on the grades of the two parties, the judge selects the jury. In order to ensure a fair trial, the tendencies of the jury to favour either defence or prosecution should be as balanced as possible. The jury therefore has to be chosen in a way that is satisfactory to both parties.
We will now make this more precise: given a pool of n potential jurors and two values di (the defence's value) and pi (the prosecution's value) for each potential juror i, you are to select a jury of m persons. If J is a subset of {1,..., n} with m elements, then D(J ) = sum(dk) k belong to J
and P(J) = sum(pk) k belong to J are the total values of this jury for defence and prosecution.
For an optimal jury J , the value |D(J) - P(J)| must be minimal. If there are several jurys with minimal |D(J) - P(J)|, one which maximizes D(J) + P(J) should be selected since the jury should be as ideal as possible for both parties.
You are to write a program that implements this jury selection process and chooses an optimal jury given a set of candidates.

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.
These values will satisfy 1<=n<=200, 1<=m<=20 and of course m<=n. The following n lines contain the two integers pi and di for i = 1,...,n. A blank line separates each round from the next.
The file ends with a round that has n = m = 0.

Output

For each round output a line containing the number of the jury selection round ('Jury #1', 'Jury #2', etc.).
On the next line print the values D(J ) and P (J ) of your jury as shown below and on another line print the numbers of the m chosen candidates in ascending order. Output a blank before each individual candidate number.
Output an empty line after each test case.

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);
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778292.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号