题意略。

思路:

这个题目开始我本来打算用个二维dp,令dp[ i ][ j ]为考虑前i个人,有j个名额的时候,我所能获取的最小差,后来发现不好转移。因为dp[ i ][ j ]有可能是+2,

也有可能是-2,这两种值对我以后的求解可能都有用。后来想再添加一维,dp[ i ][ j ][ 0 ]表示正值的最小,dp[ i ][ j ][ 1 ]表示负值的最小(绝对值的最小)。

这样dp逻辑又很复杂。最后参考了网上的解法,于是将状态定义为:

dp[ i ][ j ][ k ]表示在前i个人里考虑,有j个名额,使得sigma(p) - sigma(d)为k时,我所能获得的sigma(p + d)的最大值。

状态转移方程:dp[ i ][ j ][ k ] = max(dp[i - 1][ j ][ k ] , dp[i - 1][j - 1][k - p[i] + d[i] ] + p[ i ] + d[ i ])

只可惜我做题时只想到了正负值的问题,没有更进一步将正负值直接确定为差值,然后dp对象为p + d,从而满足题目中的第二个条件。

有时dp对象可以是次要条件,而不是首要条件,换一种方向去思考问题。

内存很紧张

//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn1 = ;
const int maxn2 = ;
const int maxn3 = ;
const int mid = maxn3>>;
const int F = 0x3f;
const int INF = 0x3f3f3f3f; struct node{
int peo,place,sub;
node(int peo = ,int place = ,int sub = ){
this->peo = peo,this->place = place,this->sub = sub;
}
}; int p[maxn2],d[maxn2],dp[maxn2][maxn1][maxn3],store[maxn2],n,m;
node path[maxn2][maxn1][maxn3]; int main(){
int cas = ;
while(scanf("%d%d",&n,&m) == && (n + m)){
for(int i = ;i <= n;++i) scanf("%d%d",&p[i],&d[i]);
int total = * m;
int low = mid - total,up = mid + total; for(int i = ;i <= n;++i){
for(int j = ;j <= m;++j){
for(int k = low;k <= up;++k){
dp[i][j][k] = -;
path[i][j][k] = node(-,-,-);
}
}
} for(int i = ;i <= n;++i) dp[i][][mid] = ; for(int i = ;i <= n;++i){
int bound = min(i,m);
for(int j = ;j <= bound;++j){
for(int k = low;k <= up;++k){
int part1 = dp[i - ][j][k];
int part2 = (k - p[i] + d[i] < low || k - p[i] + d[i] > up || dp[i - ][j - ][k - p[i] + d[i]] == -) ? - : dp[i - ][j - ][k - p[i] + d[i]] + p[i] + d[i];
dp[i][j][k] = max(part1,part2);
if(part1 == - && part2 == -) continue;
if(part1 > part2) path[i][j][k] = node(i - ,j,k);
else path[i][j][k] = node(i - ,j - ,k - p[i] + d[i]);
}
}
}
int idx;
for(int i = ;i <= total;++i){
int lft = mid - i,rht = mid + i;
int maxx = max(dp[n][m][lft],dp[n][m][rht]);
if(maxx == -) continue;
if(maxx == dp[n][m][lft]) idx = lft;
else idx = rht;
if(maxx != -) break;
}
int tail = ;
for(int i = n,j = m,k = idx;i != -;){
node temp = path[i][j][k];
int nxti = temp.peo;
int nxtj = temp.place;
int nxtk = temp.sub;
if(nxti == -) break;
if(nxtj < j) store[tail++] = i;
i = nxti,j = nxtj,k = nxtk;
}
int ans1 = ,ans2 = ;
for(int i = ;i < tail;++i){
ans1 += p[store[i]];
ans2 += d[store[i]];
}
printf("Jury #%d\n",cas++);
printf("Best jury has value %d for prosecution and value %d for defence:\n",ans1,ans2);
for(int i = tail - ;i >= ;--i) printf(" %d",store[i]);
printf("\n\n");
}
return ;
} /*
4 2
1 2
2 3
4 1
6 2 10 5
3 8
15 8
11 8
7 8
1 8
17 8
8 8
2 8
13 8
3 8 5 3
13 11
3 17
15 20
6 13
17 9 8 5
3 5
17 16
6 0
17 10
6 14
3 19
4 13
0 17
*/

POJ 1015 陪审团问题的更多相关文章

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

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

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

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

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

  4. POJ 1015 Jury Compromise 2个月后重做,其实这是背包题目

    http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从 ...

  5. (最优m个候选人 和他们的编号)Jury Compromise (POJ 1015) 难

    http://poj.org/problem?id=1015   Description In Frobnia, a far-away country, the verdicts in court t ...

  6. POJ 1015 Jury Compromise dp分组

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

  7. [Poj 1015] Jury Compromise 解题报告 (完全背包)

    题目链接:http://poj.org/problem?id=1015 题目: 题解: 我们考虑设计DP状态(因为这很显然是一个完全背包问题不是吗?) dp[j][k]表示在外层循环到i时,选了j个人 ...

  8. POJ #1015 - Jury Compromise - TODO: POJ website issue

    (poj.org issue. Not submitted yet) This is a 2D DP problem, very classic too. Since I'm just learnin ...

  9. poj 1015 Jury Compromise_dp

    题意:n个陪审团,每个陪审团有x,y值,选出m个陪审团,要求 (sum(xi)-sum(yi))最少,当 (sum(xi)-sum(yi))最少有多个,取sum(xi)+sum(yi)最大那个 ,并顺 ...

随机推荐

  1. cesium 学习(四) Hello World

    一.前言 之前的文章都是基础,搭建环境.部署Cesium.学习资料等等.现在简单入手,一个Hello World页面开发. 二.Hello World 感觉Hello World没有什么特别需要讲的, ...

  2. CentOS 下编译安装Apache

    CentOS 下编译安装Apache 卸载原有的apache 首先从 http://httpd.apache.or 下载apache源码包httpd-2.4.4.tar.gz然后从 http://ap ...

  3. python课堂整理2

    一.字节和编码 1个字节是8位二进制 utf-8 表示一个中文要用3个字节 gbk 为中国汉字发明,2个字节可表示汉字 所以 utf-8 可以读gbk编码,而gbk去读utf-8 的内容会乱码 uni ...

  4. (原创)将Datatable数据按照Excel模板格式导出

    最近遇到一个问题,就是导出数据的时候需要自定义的表头,如图 如果自己用代码写表头的话,可能会有点复杂,而且代码量很多,所以我就想了一个办法,直接在Excel里面把表头定义好,然后把数据写入Excel模 ...

  5. SSD+HDD 安装ubuntu16.04+win7双系统

    本人电脑是联想天逸100  前段时间把光驱拆了加了一个128G的SSD 顺便把SSD装上了win7  机械硬盘500G放资料和一般软件之类的   后来想要用到ubuntu  就在官网下载ubuntu1 ...

  6. canal同步MySQL数据到ES6.X

    背景: 最近一段时间公司做一个技术架构的更改,由于之前使用的solr和目前的业务不太匹配,具体原因不多说啦.所以要把数据放到Elasticsearch中进行快速的搜索,这是便产生了一个数据迁移的需求, ...

  7. 泥瓦匠 5 年 Java 的成长感悟(下)

    继续<泥瓦匠 5 年 Java 的成长感悟(上)>,大致包括下面几点: 学技术的心态 学技术的学法 工作的心态 工作的硬技能 工作的软实力 听点雷子的民谣,我就安静地感概感概.上次说写的, ...

  8. hdoj 3732 Ahui Writes Word (多重背包)

    之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!!  然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小. 时隔多日,回过头来看这道题,依旧毫无头绪....不过相比之前 ...

  9. Linux基础管道管理

    一.I/O重定向 标准输入,标准输出,标准错误 file descriptors (FD, 文件描述符或Process I/O channels); 进程使用文件描述符来管理打开的文件 [root@l ...

  10. c#小灶——标识符和关键字

    标识符 我们之前说,命名空间的名字是自己取的,类名也是自己取的,方法名也是自己取的,以后还有各种常量.变量.对象……这些名字是自己取的.这些名字,就是标识符. 标识符规则: 标识符可以包含大小写字母. ...