提议:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团。选m人的办法是:
控方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可。

题解:开始想到的是二维01背包,因为评价差的总分值最大可能就只有[-400,400],所以我们整体加上20*m就可以直接放入dp的一维来解决

     开两个数组:

   path[i][j];//选i个人的评价差为j时最后一个人的编号

   dp [i][j];//选i个人的评价差为j时最大评价和

   然后使用三重循环:第一重是枚举选择1到m个人,第二重是枚举参选的人,第三重是枚举评价差的总可能值,枚举这个人去参选每种评价差的情况

   然后判断当前这个人在这个位置时是否已经被选过了与现在计算的评价和是否大于存储的(因为评价差固定了)评价和

   接着就是注意初始化要在加20*m的位置初始化(关键),而不是(0,0)

   但是这样有bug,例如:选择135与选择246的评价差与评价和是一样的,我们可能选择了246把135忽略掉了,但是正确答案却是1356

   因此还有这个办法(网上看到的):我们把循环的位置换一下,将第二重循环放在第一重,原来第一重放在第二重,其他的不变

   这样只有固定每个参选人后才可以枚举下一个参选人,就解决这个bug了

   接下来如果把第二重循环倒叙就可以保证不会出现重复的人,这样就不用判断这个人是否之前已经被选择过(类似01背包)

   最后要注意循环顺序改变后不能回溯找路了,因为第一重循环会把路径打乱,所以我们得存储路径

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const ll INF=1LL<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
struct node
{
int d,p;
int sum,sub;
}que[Max];
vector<int> path[][Max<<];//选i个人的评价差为j时最后一个人的编号
int dp[][Max<<];//选i个人的评价差为j时最大评价和
int now[][Max<<];//存值便于回溯
int ansp,ansd,ans[];
int coun;
void dfs(int i,int j)
{
coun=;
int siz=path[i][j].size();
for(int k=;k<siz;++k)
{
ans[coun++]=path[i][j][k];
}
return;
}
void Solve(int n,int m)
{
ansd=ansp=;
int fix=*m;//右移fix
memset(dp,-,sizeof(dp));//不允许走的地方
for(int i=;i<=m;++i)
for(int j=;j<*fix;++j)
path[i][j].clear();
dp[][fix]=;//向右移动fix保证所有为非负
for(int i=;i<n;++i)//确定人后再确定下一人,这样避免出现当评论差与评论和都相同却不能存的情况
{
for(int j=m;j>;--j)//选择的人数,倒叙保证不重复(01背包)
{
for(int k=;k<*fix;++k)//评论差的值
{
int kk=k-que[i].sub;
if(kk>=&&dp[j-][kk]>=&&dp[j][k]<dp[j-][kk]+que[i].sum)
{
dp[j][k]=dp[j-][kk]+que[i].sum;
path[j][k]=path[j-][kk];//因为遍历m个人的循环在内部,所以不能回溯找路径
path[j][k].push_back(i);
}
}
}
}
for(int i=fix,j=fix;i>=;--i,++j)
{
if(dp[m][i]>=)
{
if(dp[m][j]>dp[m][i])
dfs(m,j);//找到(减去fix后的绝对值)最接近0的值
else
dfs(m,i);
break;
}
if(dp[m][j]>=)
{
dfs(m,j);
break;
}
}
for(int i=;i<m;++i)
{
ansp+=que[ans[i]].p;
ansd+=que[ans[i]].d;
}
return;
}
int main()
{
int n,m;
int coun=;
while(~scanf("%d %d",&n,&m)&&(n||m))
{
for(int i=; i<n; ++i)
{
scanf("%d %d",&que[i].d,&que[i].p);
que[i].sum=que[i].d+que[i].p;
que[i].sub=que[i].d-que[i].p;
}
Solve(n,m);
printf("Jury #%d\n",++coun);
printf("Best jury has value %d for prosecution and value %d for defence:\n",ansd,ansp);
for(int i=; i<m; ++i)
printf(" %d",ans[i]+);
printf("\n\n");
}
return ;
}

  

POJ 1015 Jury Compromise(dp坑)的更多相关文章

  1. POJ 1015 Jury Compromise dp分组

    第一次做dp分组的问题,百度的~~ http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑 ...

  2. POJ 1015 Jury Compromise dp

    大致题意: 从n个候选人中选出m个人作为陪审团.为了让陪审团的选择更公平,辩方和控方都为这n个候选人给出了满意度(辩方为D[j],控方为P[j],范围0至20).现在要使得选出的m位候选人的辩方总和与 ...

  3. 背包系列练习及总结(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 ...

  4. POJ 1015 Jury Compromise(双塔dp)

    Jury Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33737   Accepted: 9109 ...

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

    1.链接地址: http://bailian.openjudge.cn/practice/2979 http://poj.org/problem?id=1015 2.题目: 总Time Limit: ...

  6. poj 1015 Jury Compromise(背包+方案输出)

    \(Jury Compromise\) \(solution:\) 这道题很有意思,它的状态设得很...奇怪.但是它的数据范围实在是太暴露了.虽然当时还是想了好久好久,出题人设了几个限制(首先要两个的 ...

  7. poj 1015 Jury Compromise(背包变形dp)

    In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...

  8. POJ 1015 Jury Compromise【DP】

    罗大神说这题很简单,,,,然而我着实写的很难过... 题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110495#proble ...

  9. HDU POJ 1015 Jury Compromise(陪审团的人选,DP)

    题意: 在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候 ...

随机推荐

  1. JS探秘——那些你理解存在偏差的问题

    Javascript的连续赋值运算 var a = {n:1}; a.x = a = {n:2}; alert(a.x); // --> undefined 看 jQuery 源码 时发现的这种 ...

  2. (六)通过solr7的API实现商品的列表查询

    (六)通过solr7的API实现商品的列表查询 工具类: 获取 HttpSolrClient public class Constant { public static HttpSolrClient ...

  3. C# 中正则表达式 Group 分组

    在一个正则表达式中,如果要提取出多个不同的部分(子表达式项),需要用到分组功能. 在 C# 正则表达式中,Regex 成员关系如下,其中 Group 是其分组处理类. Regex –> Matc ...

  4. 封装AFNetworking

    用了一下AFNetworking感觉比ASIHttprequest 真心好用一些,因为我还是个初学者吧,很多ASIHttprequest 的功能还没有用到,与ASIHttprequest 不用的是AF ...

  5. Django的admin定制

    1,models编写 #encoding=utf-8 from django.db import models # Create your models here. class BookInfo(mo ...

  6. python基础——函数参数

    课上老师已经讲过函数(func)的参数(args)传递. 之前学习了根据位置传递对应的参数,下面会介绍其他参数传递方式. 之前的位置传参: def f(a,b,c): return a+b+c pri ...

  7. LinuxCentos系统安装Nginx过程记录

    网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务就是Web网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web网络服务是一种被动访问的服务程 ...

  8. numpy利用数组进行数据处理

    将条件逻辑表述为数组运算 numpy.where()是一个三目运算的表达式 In [34]: xarr = np.array([1.1,1.2,1.3,1.4,1.5]) In [35]: yarr ...

  9. java.lang.NoClassDefFoundError: org/springframework/expression/PropertyAccessor

    这个异常原因种类不一,网上有各个版本,本人的是因为缺少了spring-expression-3.2.1.RELEASE.jar 2015-9-18 23:19:11 org.apache.catali ...

  10. Hibernate关联关系的CRUD

    本文以Group和User(一对多.多对一)双向关联为例,介绍关联关系的CRUD   下面先介绍两个属性 cascade:只影响CRUD中的CUD,即存储(save).更新(update).删除(de ...