HDU 1015 Jury Compromise 01背包
题目链接:
http://poj.org/problem?id=1015
Jury Compromise
Time Limit: 1000MSMemory Limit: 65536K
#### 问题描述
> 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.
#### 输入
> 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 The file ends with a round that has n = m = 0.
#### 输出
> 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.
####样例输入
> 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
题意
给你n个人,每个人有权值a[i],b[i],现在要选出m个人,使得abs(sigma(a[i])-sigma(b[i]))最小,如果存在多解,则选sigma(a[i])+sigma(b[i])最大的任意一个。
题解
咋看下dp不能做,因为直接维护abs(sigma(a[i])-sigma(b[i]))这个东西根本不满足子问题具有最优子结构的性质。
但是!我们应该马上注意到数据范围很小,因此我们可以尝试在状态上做些手脚,使这个问题能够用dp来做。
不难发现,如果选m个,那么sigma(a[tt]-b[tt])的范围是[-20*m,20*m]
,这并不会很大,所以我们可以定义dp[i][j][k]表示考虑了前i个人,选了j个人,sigma(a[tt]-b[tt])+400=k的情况。然后最后枚举下k就可以啦,也就是我们把最优问题转换成了判定问题,并且能用dp来解决。(当然,还要记得维护下sigma(a[tt]+b[tt])最大。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<sstream>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
bool dp[222][22][888];
int ans[222][22][888];
PII arr[222];
vector<int> lis;
void print(int i,int j,int k){
if(i==0){ return; }
int a=arr[i].X,b=arr[i].Y;
int c=a-b;
if(dp[i-1][j][k]&&dp[i-1][j-1][k-c]){
if(ans[i-1][j][k]>ans[i-1][j-1][k-c]+a+b){
print(i-1,j,k);
}else{
print(i-1,j-1,k-c);
lis.pb(i);
}
}else if(dp[i-1][j][k]){
print(i-1,j,k);
}else if(dp[i-1][j-1][k-c]){
print(i-1,j-1,k-c);
lis.pb(i);
}
}
int main() {
int n,m,kase=0;
while(scf("%d%d",&n,&m)==2&&n) {
lis.clear();
for(int i=1; i<=n; i++) {
scf("%d%d",&arr[i].X,&arr[i].Y);
}
clr(dp,0);
clr(ans,0);
rep(i,0,222) dp[i][0][400]=1;
for(int i=1; i<=n; i++) {
int a=arr[i].X,b=arr[i].Y;
int c=a-b;
for(int j=1; j<=m; j++) {
for(int k=0; k<=800; k++) {
if(k-c>=0&&k-c<=800) {
if(dp[i-1][j][k]&&dp[i-1][j-1][k-c]) {
dp[i][j][k]=1;
ans[i][j][k]=max(ans[i-1][j][k],ans[i-1][j-1][k-c]+a+b);
} else if(dp[i-1][j][k]) {
dp[i][j][k]=1;
ans[i][j][k]=ans[i-1][j][k];
} else if(dp[i-1][j-1][k-c]) {
dp[i][j][k]=1;
//这里a+b漏了,调了好久xrz
ans[i][j][k]=ans[i-1][j-1][k-c]+a+b;
}
} else {
dp[i][j][k]=dp[i-1][j][k];
ans[i][j][k]=ans[i-1][j][k];
}
}
}
}
int Mi=INF,pos=-1,Ma=-1;
for(int i=0; i<=800; i++) {
if(dp[n][m][i]) {
if(Mi>abs(i-400)) {
Mi=abs(i-400);
Ma=ans[n][m][i];
pos=i;
} else if(Mi==abs(i-400)&&ans[n][m][i]>Ma) {
Ma=ans[n][m][i];
pos=i;
}
}
}
print(n,m,pos);
int a=0,b=0;
rep(i,0,lis.sz()){ a+=arr[lis[i]].X,b+=arr[lis[i]].Y; }
prf("Jury #%d\n",++kase);
prf("Best jury has value %d for prosecution and value %d for defence:\n",a,b);
rep(i,0,lis.sz()) prf(" %d",lis[i]); prf("\n\n");
}
return 0;
}
//end-----------------------------------------------------------------------
Notes
数据小,没有最优子问题结构的,可以考虑判定性。
HDU 1015 Jury Compromise 01背包的更多相关文章
- poj 1015 Jury Compromise(背包+方案输出)
\(Jury Compromise\) \(solution:\) 这道题很有意思,它的状态设得很...奇怪.但是它的数据范围实在是太暴露了.虽然当时还是想了好久好久,出题人设了几个限制(首先要两个的 ...
- 背包系列练习及总结(hud 2602 && hdu 2844 Coins && hdu 2159 && poj 1170 Shopping Offers && hdu 3092 Least common multiple && poj 1015 Jury Compromise)
作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢htt ...
- HDU 2602 Bone Collector(01背包裸题)
Bone Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 2546 饭卡(01背包裸题)
饭卡 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- POJ 1015 Jury Compromise (算竞进阶习题)
01背包 我们对于这类选或者不选的模型应该先思考能否用01背包来解. 毫无疑问物体的价值可以看成最大的d+p值,那么体积呢?题目的另一个限制条件是d-p的和的绝对值最小,这启发我们把每个物体的d-p的 ...
- HDU 2602 - Bone Collector - [01背包模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Many years ago , in Teddy’s hometown there was a ...
- HDU 5234 Happy birthday 01背包
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5234 bc:http://bestcoder.hdu.edu.cn/contests/con ...
- poj1015 Jury Compromise【背包】
Jury Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions:32355 Accepted:8722 ...
- POJ 1015 Jury Compromise(dp坑)
提议:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候选 ...
随机推荐
- js call().apply().bind()的用法
function Person(age) { this.age = age; } Person.prototype.sayHi = function (x, y) { console.log((x + ...
- Linux下用mail 命令给163邮箱发送邮件!
linux上的邮件客户端比较多,找一个平时用的比较多mail命令来试试!! 环境 :centos7: 注意 : 服务器必须得有外网才行,qq邮箱作为在linux上的发送端邮箱,经过测试 163 和qq ...
- 《锋利的JQ》摘抄(一) jq基础篇
前言:第一次写博客有点紧张233333,我会在博客里放一下在赌这本书过程中遇到的一些有用的知识点,希望等帮助到大家.好了正题开始(只要是我不知道该说啥了= =) 一,资源(在w3cfuns资源中可以 ...
- Delphi泛型动态数组的扩展--转贴
此文章转载于http://www.raysoftware.cn/?p=278&tdsourcetag=s_pcqq_aiomsg的博客 从Delphi支持泛型的第一天起就有了一种新的动态数组类 ...
- 在myeclipse等IDE中添加本地的dtd与schema约束文件
*针对没有网络无法正确引入dtd而使用不了提示的问题 (配置完后重启IDE) window->perferences- > 搜索xml c 找到xml catalog 右边点击 a ...
- 20145234黄斐《java程序设计》第十三周代码检查
在IDEA中对P145 MathTool.java 使用JUnit进行单元测试,测试用例不少于三个,要包含正常情况,边界情况. 提交测试代码和运行结果截图,加上学号水印,提交码云代码链接. 码云链接 ...
- 4543: [POI2014]Hotel加强版
4543: [POI2014]Hotel加强版 链接 分析: f[u][i]表示子树u内,距离u为i的点的个数,g[u][i]表示在子树u内,已经选了两个深度一样的点,还需要在距离u为i的一个点作为第 ...
- 有哪些 Bootstrap 的学习案例?
bootstrap经典实用案例 bootstrap经典实用案例(非常详细),从菜鸟到高手的过程是艰辛的,你渴望救助.这本教程就是你无言的助手,默默的帮你到永远. 带奋斗一起飞翔,因为有了它,让我拥有理 ...
- 资产管理系统 CMDB 讲解
两年前笔者在一个中小型互联网公司做运维,当时我们经理在机房,花了半天找一台服务器,但是服务器搞错了,悲剧了^.^! 当时我们的做法是用了一个 Excel,很多时候更新不及时,重启一台机器.拔一根网线都 ...
- python实现屏保计时器
什么都不说先上图吧,Python 初学者实现屏保计时器 原理:利用 Python turtle 库实现快速画图,每隔一秒钟擦除屏幕,然后获得电脑实时时间,再次画图,呈现动态时间. 关于数字如果画,可以 ...