• OpenJudge 2979 陪审团的人选 / Poj 1015 Jury Compromise


    1.链接地址:

    http://bailian.openjudge.cn/practice/2979

    http://poj.org/problem?id=1015

    2.题目:

    总Time Limit:
    1000ms
    Memory Limit:
    65536kB
    Description
    在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团。选m人的办法是:

    控 方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总 分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可。
    Input
    输入包含多组数据。每组数据的第一行是两个整数n和m,n是候选人数目,m是陪审团人数。注意,1<=n<=200, 1<=m<=20 而且 m<=n。接下来的n行,每行表示一个候选人的信息,它包含2个整数,先后是控方和辩方对该候选人的打分。候选人按出现的先后从1开始编号。两组有 效数据之间以空行分隔。最后一组数据n=m=0
    Output
    对每组数据,先输出一行,表示答案所属的组号,如 'Jury #1', 'Jury #2', 等。接下来的一行要象例子那样输出陪审团的控方总分和辩方总分。再下来一行要以升序输出陪审团里每个成员的编号,两个成员编号之间用空格分隔。每组输出数据须以一个空行结束。
    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 
    Source
    Southwestern European Regional Contest 1996, POJ 1015, 程序设计实习2007

    3.思路:

    这题自己没想到思路,参照了《程序设计导引及在线实践》的思路

    动态规划题目,使用深度搜索的话会超时

    4.代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 
      6 using namespace std;
      7 
      8 const int maxDiff = 400;
      9 
     10 int cmp(const void* a,const void *b)
     11 {
     12     int int_a = *((int *)a);
     13     int int_b = *((int *)b);
     14 
     15     return int_a - int_b;
     16 }
     17 
     18 int main()
     19 {
     20     //freopen("C://input.txt","r",stdin);
     21 
     22     int i,j,k;
     23     int temp;
     24     int temp_path,temp_diff;
     25 
     26     int n,m;
     27     cin >> n >> m;
     28 
     29     int count = 1;
     30     while(n != 0 || m != 0)
     31     {
     32         int *arr_sum = new int[n];
     33         int *arr_diff = new int[n];
     34 
     35         bool *arr_used = new bool[n];
     36         memset(arr_used,0,sizeof(bool) * n);
     37 
     38         int int_a,int_b;
     39         for(i = 0; i < n; ++i)
     40         {
     41             cin >> int_a >> int_b;
     42             arr_sum[i] = int_a + int_b;
     43             arr_diff[i] = int_a - int_b;
     44         }
     45 
     46         int **dp = new int*[m];
     47         for(i = 0; i < m; ++i)
     48         {
     49             dp[i] = new int[maxDiff * 2 + 1];
     50             for(j = 0; j <= maxDiff * 2; ++j) dp[i][j] = -1;
     51         }
     52 
     53         int **path = new int*[m];
     54         for(i = 0; i < m; ++i) path[i] = new int[maxDiff * 2 + 1];
     55 
     56         for(i = 0; i < n; ++i)
     57         {
     58             temp = arr_diff[i] + maxDiff;
     59             if(dp[0][temp] < arr_sum[i])
     60             {
     61                 dp[0][temp] = arr_sum[i];
     62                 path[0][temp] = i;
     63             }
     64 
     65             //cout << "dp[0][" << temp << "]="  << dp[0][temp] << "path[0][" << temp << "]=" << path[0][temp] << endl;
     66         }
     67 
     68 
     69         for(i = 1; i < m; ++i)
     70         {
     71             for(j = 0; j <= maxDiff * 2; ++j)
     72             {
     73                 if(dp[i - 1][j] != -1)
     74                 {
     75 
     76                     temp_diff = j;
     77                     for(k = i - 1; k >= 0; --k)
     78                     {
     79                         temp_path = path[k][temp_diff];
     80                         arr_used[temp_path] = true;
     81                         temp_diff = temp_diff - arr_diff[temp_path];
     82                     }
     83 
     84                     for(k = 0; k < n; ++k)
     85                     {
     86                         if(!arr_used[k])
     87                         {
     88                             temp = j + arr_diff[k];
     89                             if(dp[i][temp] == -1 || (dp[i][temp] < dp[i - 1][j] + arr_sum[k]))
     90                             {
     91                                 dp[i][temp] = dp[i - 1][j] + arr_sum[k];
     92                                 path[i][temp] = k;
     93                             }
     94                         }
     95                     }
     96 
     97 
     98                     temp_diff = j;
     99                     for(k = i - 1; k >= 0; --k)
    100                     {
    101                         temp_path = path[k][temp_diff];
    102                         arr_used[temp_path] = false;
    103                         temp_diff = temp_diff - arr_diff[temp_path];
    104                     }
    105                 }
    106             }
    107 
    108         }
    109 
    110         int res_idx;
    111         for(i = 0; i <= maxDiff; ++i)
    112         {
    113             if(dp[m - 1][maxDiff - i] != -1 || dp[m - 1][maxDiff + i] != -1)
    114             {
    115                 if(dp[m - 1][maxDiff - i] == -1) res_idx = i;
    116                 else if(dp[m - 1][maxDiff + i] == -1) res_idx = - i;
    117                 else
    118                 {
    119                     res_idx = (dp[m - 1][maxDiff + i] > dp[m - 1][maxDiff - i] ? i : (-i));
    120                 }
    121                 break;
    122             }
    123         }
    124 
    125         cout << "Jury #" << count++ << endl;
    126         cout << "Best jury has value " << (dp[m - 1][res_idx + maxDiff] + res_idx) / 2<< " for prosecution and value " << (dp[m - 1][res_idx + maxDiff] - res_idx) / 2<< " for defence:" << endl;
    127 
    128         temp_diff = res_idx + maxDiff;
    129         int *arr_res = new int[m];
    130         for(i = m - 1; i >= 0; --i)
    131         {
    132             temp_path = path[i][temp_diff];
    133             arr_res[i] = temp_path + 1;
    134             temp_diff = temp_diff - arr_diff[temp_path];
    135         }
    136         qsort(arr_res,m,sizeof(int),cmp);
    137 
    138         for(i = 0; i < m; ++i) cout << " " << arr_res[i];
    139         cout << endl;
    140 
    141         delete [] arr_res;
    142 
    143         cout << endl;
    144 
    145         delete [] arr_sum;
    146         delete [] arr_diff;
    147         
    148         for(i = 0; i < m; ++i) delete [] dp[i];
    149         delete [] dp;
    150 
    151 
    152 
    153         for(i = 0; i < m; ++i) delete [] path[i];
    154         delete [] path;
    155 
    156         cin >> n >> m;
    157     }
    158 
    159     return 0;
    160 }
  • 相关阅读:
    TcIC(Teamcenter集成CatiaV5)的安装
    centos7上使用bind解析子域名
    Windows10 家庭版(1903/1909)中用RDPWrapper-v1.6.2和autoupdate补丁开启远程桌面功能
    修改SQL Server Express 2019 sa用户密码的方法
    微星B450主板安装64G内存的一个小招数
    缩小xfs文件系统的CentOS/RedHat虚拟机硬盘的迂回方法
    MQL命令的打开方式
    台电TBook二合一本全新安装Windows10
    django_auth_ldap
    开始认真学计算机网络----computer network学习笔记(一)
  • 原文地址:https://www.cnblogs.com/mobileliker/p/3577263.html
Copyright © 2020-2023  润新知