POJ1015 DP
| Time Limit: 1000MS | Memory Limit: 65536K | |||
| Total Submissions: 28927 | Accepted: 7676 | Special Judge | ||
Description
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
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
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
Hint
Source
/*
为叙述问题方便,现将任一选择方案中,辩方总分和控方总分之差简称为“辩控差”,
辩方总分和控方总分之和称为“辩控和”。第i 个候选人的辩方总分和控方总分之差
记为V(i),辩方总分和控方总分之和记为S(i)。现用dp(j, k)表示,取j 个候选人,
使其辩控差为k 的所有方案中,辩控和最大的那个方案(该方案称为“方案dp(j, k)”)
的辩控和。并且,我们还规定,如果没法选j 个人,使其辩控差为k,那么dp(j, k)的
值就为-1,也称方案dp(j, k)不可行。本题是要求选出m 个人,那么,如果对k 的
所有可能的取值,求出了所有的dp(m, k) (-20×m≤ k ≤ 20×m),那么陪审团方案自然
就很容易找到了。
问题的关键是建立递推关系。需要从哪些已知条件出发,才能求出dp(j, k)呢?
显然,方案dp(j, k)是由某个可行的方案dp(j-1, x)( -20×m ≤ x ≤ 20×m)演化而来的。
可行方案dp(j-1, x)能演化成方案dp(j, k)的必要条件是:存在某个候选人i,i
在方案dp(j-1, x)中没有被选上,且x+V(i) = k。在所有满足该必要条件的dp(j-1, x)中
,选出 dp(j-1, x) + S(i) 的值最大的那个,那么方案dp(j-1, x)再加上候选人i,就
演变成了方案 dp(j, k)。这中间需要将一个方案都选了哪些人都记录下来。不妨将方案
dp(j, k)中最后选的那个候选人的编号,记在二维数组的元素path[j][k]中。那么方案
dp(j, k)的倒数第二个人选的编号,就是path[j-1][k-V[path[j][k]]]。假定最后算出
了解方案的辩控差是k,那么从path[m][k]出发,就能顺藤摸瓜一步步回溯求出所有被选中的候选人。
初始条件,只能确定dp(0, 0) = 0,其他均为-1。由此出发,一步步自底向上递推,就
能求出所有的可行方案dp(m, k)( -20×m ≤ k ≤ 20×m)。实际解题的时候,会用一个二维
数组dp 来存放dp(j, k)的值。而且,由于题目中辩控差的值k 可以为负数,而程序中数
租下标不能为负数,所以,在程序中不妨将辩控差的值都加上修正值fix=400,以免下标
为负数导致出错。
为什么fix=400?这是很显然的,m上限为20人,当20人的d均为0,p均为20时,会出现辨
控差为-400。修正后回避下标负数问题,区间整体平移,从[-400,400]映射到[0,800]。
此时初始条件修正为dp(0, fix) = 0,其他均为-1。
DP后,从第m行的dp(m, fix)开始往两边搜索最小|D-P| 即可,第一个不为dp[m][k]!=-1的
位置k就是最小|D-P|的所在。
最后就是求m个人的D和P,由于D+P = dp(m, |D-P| ) ,|D-P|已知。
那么D= (D+P + |D-P| )/2 , P=(D+P-|D-P| ) / 2
计算D和P时注意修正值fix
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int d[],p[],c[],h[],f[][],path[][];
int main()
{
int n,m,cas=;
while(scanf("%d%d",&n,&m)&&(n+m)){
for(int i=;i<=n;i++){
scanf("%d%d",&d[i],&p[i]);
c[i]=d[i]-p[i];
h[i]=d[i]+p[i];
}
memset(f,-,sizeof(f));
memset(path,,sizeof(path));
int M=m*;
f[][M]=;
for(int i=;i<m;i++){
for(int j=;j<=M*;j++){
if(f[i][j]==-) continue;
for(int k=;k<=n;k++){
if(f[i][j]+h[k]>f[i+][j+c[k]]){
int t1=i,t2=j;
while(t1>&&path[t1][t2]!=k){
t2-=c[path[t1][t2]];
t1--;
}
if(t1==){
f[i+][j+c[k]]=f[i][j]+h[k];
path[i+][j+c[k]]=k;
}
}
}
}
}
int i;
for(i=;;i++){
if(f[m][M+i]!=-) break;
if(f[m][M-i]!=-) break;
}
int ans1,ans2,t1=m,t2;
if(f[m][M+i]>f[m][M-i]){
ans1=(i+f[m][M+i])/;
ans2=f[m][M+i]-ans1;
t2=M+i;
}
else{
ans1=(-i+f[m][M-i])/;
ans2=f[m][M-i]-ans1;
t2=M-i;
}
printf("Jury #%d\n",++cas);
printf("Best jury has value %d for prosecution and value %d for defence:\n",ans1,ans2);
int tmp[],cnt=;
while(t1){
tmp[cnt++]=path[t1][t2];
t2-=c[path[t1][t2]];
t1--;
}
sort(tmp,tmp+cnt);
for(int j=;j<cnt;j++) printf(" %d",tmp[j]);
printf("\n\n");
}
return ;
}
POJ1015 DP的更多相关文章
- POJ1015 && UVA - 323 ~Jury Compromise(dp路径)
In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...
- poj1015 正解--二维DP(完全背包)
题目链接:http://poj.org/problem?id=1015 错误解法: 网上很多解法是错误的,用dp[i][j]表示选择i个人差值为j的最优解,用path[i][j]存储路径,循环次序为“ ...
- poj1015陪审团——DP+路径记录
题目:http://poj.org/problem?id=1015 DP的第一维是选了几个人,第二维是当前D与P的差值,而值存的是当前D与P的和: 技巧1:通过平移避免负角标,即代码中的fix: 技巧 ...
- poj1015【DP.......无奈了】
首先,读题,真是一窍不通.后来看完程序的意思,才明白吧.. 题意: n个人中选m个,条件是取sum|D-P|最小,当有|D-P|相同的时候取|D+P|最大的.然后输出那些m个人的sumD,sumP,最 ...
- $POJ1015\ Jury\ Compromise\ Dp$/背包
洛谷传送门 $Sol$ 这是一道具有多个“体积维度”的$0/1$背包问题. 把$N$个候选人看做$N$个物品,那么每个物品有如下三种体积: 1.“人数”,每个候选人的“人数”都是$1$,最终要填满容积 ...
- POJ-1015 Jury Compromise(dp|01背包)
题目: In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting ...
- POJ1015陪审团(Jury Compromise)——dp+路径记录
题目:http://poj.org/problem?id=1015 差值是有后效性的,所以“转化为可行性”,开一维记录“能否达到这个差值”. 当然可以开两维分别记录 a 和 b,但 “值只是0或1” ...
- 【poj1015】 Jury Compromise
http://poj.org/problem?id=1015 (题目链接) 题意 随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m 人组成陪审团.选m人的办法是:控方和辩方会根据对候选人的喜欢 ...
- DP总结 ——QPH
常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一 ...
随机推荐
- 腾讯地图和百度地图的PHP相互转换
/** * 百度地图---->腾讯地图 * @param double $lat 纬度 * @param double $lng 经度 * @return array(); */ functio ...
- MySQL数据库怎么截取字符串?
函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...
- [精通Python自然语言处理] Ch1 - 将句子切分为单词
实验对比了一下三种切分方式: 1,2 : nltk.word_tokenize : 分离缩略词,(“Don't” =>'Do', "n't") 表句子切分的“,” &quo ...
- codeforces 301D Yaroslav and Divisors(树状数组)
Yaroslav has an array p = p1, p2, ..., pn (1 ≤ pi ≤ n), consisting of n distinct integers. Also, he ...
- 常用实例:js格式化手机号为3 4 4形式
如何在填写手机号时将格式转换为3 4 4形式: 一:填写手机号时,在keyup事件中判断长度,符合条件时在值后面插入空格 $('#username').on('keyup',function(e){ ...
- http-bio-8080"-exec-6"(转)
现象如下: Tomcat7启动后,后台抛出如下异常,前台一直无法登陆Exception in thread ""http-bio-8080"-exec-6" j ...
- Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件
作者 : 万境绝尘 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/36438365 示例代码下载 : -- CSDN : htt ...
- “今日校园” App 用户体验分析
一.背景 为进一步提升信息化应用水平,更好的服务师生,南通大学智慧校园移动端APP“今日校园”定于11月5日正式上线运行.登陆APP可浏览学校新闻.校园生活.各部门微信公众号等内容,查看校内通知.校内 ...
- 2019寒假训练营寒假作业(三) MOOC的网络空间安全概论笔记部分
目录 第五章 网络攻防技术 5.1:网络信息收集技术--网络踩点 信息收集的必要性及内容 网络信息收集技术 网络踩点(Footprinting) 网络踩点常用手段 5.2:网络信息收集技术 --网络扫 ...
- FastReport.net 常用方法
一.页面设置 情景:FastReport设计器页面默认设置为A4纸,但如果需要显示的字段过多,这时就出现了页面的大小无法满足完整显示所需内容的问题. 解决:出现这个问题后,我们可以在来到"文 ...