详见AcWing 280. 陪审团 - AcWing

在一个遥远的国家,一名嫌疑犯是否有罪需要由陪审团来决定。

陪审团是由法官从公民中挑选的。

法官先随机挑选 N 个人(编号 1,2…,N)作为陪审团的候选人,然后再从这 N 个人中按照下列方法选出 M 人组成陪审团。

首先,参与诉讼的控方和辩方会给所有候选人打分,分值在 0 到 20 之间。

第 i 个人的得分分别记为 p[i] 和 d[i]。

为了公平起见,法官选出的 M 个人必须满足:辩方总分 D 和控方总分 P 的差的绝对值 |D−P| 最小。

如果选择方法不唯一,那么再从中选择辨控双方总分之和 D+P 最大的方案。

求最终的陪审团获得的辩方总分 D、控方总分 P,以及陪审团人选的编号。

注意:若陪审团的人选方案不唯一,则任意输出一组合法方案即可。

输入格式

输入包含多组测试数据。

每组测试数据第一行包含两个整数 N 和 M。

接下来 N 行,每行包含两个整数 p[i] 和 d[i]。

每组测试数据之间隔一个空行。

当输入数据 N=0,M=0 时,表示结束输入,该数据无需处理。

输出格式

对于每组数据,第一行输出 Jury #C,C 为数据编号,从 1 开始。

第二行输出 Best jury has value P for prosecution and value D for defence:,P 为控方总分,D 为辩方总分。

第三行输出按升序排列的陪审人选编号,每个编号前输出一个空格。

每组数据输出完后,输出一个空行。

数据范围

1≤N≤200,

1≤M≤20

0≤p[i],d[i]≤20

输入样例:

4 2

1 2

2 3

4 1

6 2

0 0

输出样例:

Jury #1

Best jury has value 6 for prosecution and value 4 for defence:

2 3

状态确立:

状态确立需要考虑我们要维护哪些量,这个数据它有什么元素。在这道题中,变量有

1.目前已选的人数

2.目前的分数差

3.对于每一个人,他的分数不同,第i个人的i不同对结果也有影响,i也要参与维护

我们需要求的结果是当前分数差最小的分数最大的值。

虽然题目要求的是陪审团的人选方案,但本质仍然是求最大值。

f[i][j][k]表示从前i个人中找到j个人,分数差为k的最大分数值。

状态转移:

一、不选,则f[i][j][k]=f[i-1][j][k]。
二、选,f[i][j][k]=f[i-1][j-1][k-(p[i]-d[i])]+d[i]+p[i];

需要注意的事项:

1.数组下标不存在负数,但这道题的分数差可能是负数。要给整体加上一个向上的偏移量(20 * 20  = 400)。所以数组下标为0 - 800;

2.应该先判断是否能加入第i人,也就是说要先判断j减去1后会不会小于0。

判断答案:

找最小差值v。
我们先将v设为0(也就是最理想的情况)。
然后判断,方法是看f[n][m][v+base]和f[n][m][base-v]是否都小于0,(base为偏移量)
若都小于0,则说明不存在此种情况,则v++(我们初始化把f数组设为无穷大),利用while循环找出最小的v值。
此外可能出现base+v和base-v都合法的情况,则需要判断哪一个的总分最大(就是将f值比大小)
将v赋成那个方案所对应的v值(注意加上base)

得到方案:

方法是反过来推。首先从f[i][j][v](i=n,j=m,这里的v是上面找出来的最小差值加上base)开始,
判断他是由哪一种情况得来(选与不选),若是不选,直接将i--;若选,记录人选,将v减掉该人的差值,再i--,j--。

代码:

#include<bits/stdc++.h>using namespace std;const int N = 210, M = 805, base = 400;int n, m;
int p[N], d[N];
int f[N][21][M];
int ans[N];int main()
{int T = 1;while (scanf("%d%d", &n, &m), n || m){for (int i = 1; i <= n; i ++ ) scanf("%d%d", &p[i], &d[i]);memset(f, -0x3f, sizeof f);f[0][0][base] = 0;for (int i = 1; i <= n; i ++ )for (int j = 0; j <= m; j ++ )for (int k = 0; k < M; k ++ ){f[i][j][k] = f[i - 1][j][k];int t = k - (p[i] - d[i]);if (t < 0 || t >= M) continue;if (j < 1) continue;f[i][j][k] = max(f[i][j][k], f[i - 1][j - 1][t] + p[i] + d[i]);}int v = 0;while (f[n][m][base - v] < 0 && f[n][m][base + v] < 0) v ++ ;if (f[n][m][base - v] > f[n][m][base + v]) v = base - v;else v = base + v;int cnt = 0;int i = n, j = m, k = v;while (j){if (f[i][j][k] == f[i - 1][j][k]) i -- ;else{ans[cnt ++ ] = i;k -= (p[i] - d[i]);i --, j -- ;}}int sp = 0, sd = 0;for (int i = 0; i < cnt; i ++ ){sp += p[ans[i]];sd += d[ans[i]];}printf("Jury #%d\n", T ++ );printf("Best jury has value %d for prosecution and value %d for defence:\n", sp, sd);sort(ans, ans + cnt);for (int i = 0; i < cnt; i ++ ) printf(" %d", ans[i]);puts("\n");}return 0;
}

陪审团(算法竞赛进阶指南)相关推荐

  1. 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩

    文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...

  2. 《算法竞赛进阶指南》数论篇

    <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSGS <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSG ...

  3. 《算法竞赛进阶指南(by 李煜东)》习题题解 集合

    又是笔者给自己挖的大坑. 这里是李煜东所著<算法竞赛进阶指南(by 李煜东)>的习题题解集合. 有任何错误请在对应文章下反馈或联系 nicest1919@163.com ,谢谢 qwq 从 ...

  4. CH5202 自然数拆分Lunatic版(算法竞赛进阶指南,完全背包)

    算法竞赛进阶指南,278页,完全背包 本题要点: 1.把完全背包的代码改改即可.常规的完全背包: 有n个物品,每个物品的体积是v[i], 价值是w[i], 求装到大小为m的大背包,能获得的最大价值(每 ...

  5. 中位数--《算法竞赛进阶指南》(货仓选址和七夕祭问题详解)

    中位数 今天又和大家见面了啦~ 依旧是 <算法竞赛进阶指南>的学习哦~ 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本.种群或概 ...

  6. 金字塔(算法竞赛进阶指南)

    虽然探索金字塔是极其老套的剧情,但是有一队探险家还是到了某金字塔脚下. 经过多年的研究,科学家对这座金字塔的内部结构已经有所了解. 首先,金字塔由若干房间组成,房间之间连有通道. 如果把房间看作节点, ...

  7. AcWing 122. 糖果传递【贪心】【《算法竞赛进阶指南》,微软面试题 , HAOI2008】

    AcWing 122. 糖果传递 一.题目链接 二.题目分析 (一)算法标签 (二)解题思路 三.AC代码 四.其它题解 一.题目链接 AcWing 122. 糖果传递 进阶题目 AcWing 105 ...

  8. 算法竞赛进阶指南 骑士放置

    4: 最大独立集 :选出最多的点,使得选出的点之间没有边. 求最大独立集:选出最小的点可以破坏所有的边 <==>最小点覆盖 <==>最大匹配数. 假设最大匹配数为m,共有n个点 ...

  9. 算法竞赛进阶指南 萌新入门!

    算法竞赛进阶指南 文章目录 算法竞赛进阶指南 前言 一.介绍本书 二.如何阅读本书 三.总结 **笔记思路和结构 ** 算法竞赛进阶指南 这篇文章就简单的写一下吧! 前言 ​ 作为一个想要入坑的算法的 ...

  10. 算法竞赛进阶指南0x3A 博弈论之SG函数

    算法竞赛进阶指南0x3A 博弈论之SG函数

最新文章

  1. 无法连接NVIDIA驱动:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver
  2. String直接赋值和使用new的区别
  3. [Swift]LeetCode513. 找树左下角的值 | Find Bottom Left Tree Value
  4. HTML5 Canvas Text实例1
  5. 科大星云诗社动态20211130
  6. php判断秒为两位数,判“新”函数:得到今天与明天的秒数
  7. Eclipse常用插件下载地址
  8. linux常用特殊符号
  9. 卡巴斯基安全浏览器_知名安全软件耍流氓!擅自监控用户,双十一绝不应该成为流氓软件的狂欢!...
  10. linux vi 文件查找,linux几种常见的文件内容查找和替换命令
  11. 个人辅助带后台纯HTML网站源码
  12. 【学习方法】常见算法在实际项目中的应用
  13. java获取当前年第一天_java中如何获取系统时间的当前年份以及年份的第一天和最后一天...
  14. mipi的dsi全称_MIPI-DSI/CSI协议介绍
  15. 【NLP】文本匹配——Enhanced LSTM for Natural Language Inference阅读与总结
  16. 汇编语言||存储单元,存储字长,存储字,存储容量的理解
  17. 基于涂鸦智能开发的墨水屏座位管理器——2.嵌入式功能实现篇
  18. Linux系统中VI或VIM输入时小键盘无法使用
  19. 2021年秋招面试真题以及面试技巧分享
  20. EMC、Pure和NetApp推新品,NAS闪存场景在哪里

热门文章

  1. 为什么物理诺奖颁给量子信息科学?——量子信息的过去、现在和未来
  2. 川大计算机系导师,川大计算机学院硕士生导师简介
  3. Wi-Fi Mesh协议(1)
  4. Linux设备驱动开发基础
  5. 机器人涂装工程师岗位英文缩写_公司里各职位名称的英文缩写
  6. nefuoj1487时空乱流
  7. 史上最牛最强的linux学习笔记 7.用户和用户组管理
  8. 三十六洞天 七十二福地
  9. mysqldump命令备份数据 mysql备份数据
  10. NCX SQL编程规范