题目链接:http://poj.org/problem?id=1015

题目:

题解:

我们考虑设计DP状态(因为这很显然是一个完全背包问题不是吗?)

dp[j][k]表示在外层循环到i时,选了j个人,此时辩方总分和控方总分差值为k的时,辩方和控方的总分的和的最大值

dp[j][k+a[i]-b[i]] = max (dp[j][k + a[i] - b[i]] , dp[j][k] + a[i] + b[i])

因为是完全背包,所以我们需要写一个search函数判断当前转移的状态是否已经选过了i,这样我们需要记录一个d[j][k]数组表示在dp[j][k]的状态是选哪一个人转移过来的,这恰好也是题目要求我们处理出来的

题解其实就是上述部分了

题外话:

我们考虑不写那个search函数,然后把j这一维倒序循环,根据《算法竞赛进阶指南》,这样的做法是可以的,但是笔者尝试之后还做不到,碰到的问题就是假设dp[j][k+a[i]-b[i]]被dp[j-1][k]转移得到,此时我们可以确定dp[j-1][k]这个状态没有选择i这个人。

但是在之后的循环中,dp[j-1][k]可能会被再次更新,我们要是只是统计答案的话这并没有什么影响,但是我们在d数组回溯的时候就会得到错误的转移,因为dp[j-1][k]可能被i更新,于是d[j-1][k]变成了i。补充:但是在我的AC代码里,显然是可以避免这种情况的,因为dp[j-1][k]不可能再被更新

除此之外,我发现i循环放在最外面是不行的。这是为什么?若是有读者知道请在评论区留言。

AC代码(加了search函数)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; int n,m,fix,time;
int a[],b[],dp[][],d[][],id[];
inline int read()
{
char ch=getchar();
int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
bool search(int j,int k,int i)
{
while (j&&d[j][k]!=i)
{
int o=d[j][k];
k-=a[o]-b[o];
j--;
}
if (j) return false;
return true;
}
int main()
{
while ()
{
n=read();m=read();
if (!n) break;
for (int i=;i<=n;i++)
{
a[i]=read();b[i]=read();
}
memset(dp,-,sizeof(dp));
memset(d,,sizeof(d));
fix=m*;
dp[][fix]=;
for (int j=;j<=m;j++)
for (int k=;k<=fix<<;k++)
if (dp[j-][k]>=)
{
for (int i=;i<=n;i++)
if (dp[j-][k]+a[i]+b[i]>dp[j][k+a[i]-b[i]]&&search(j-,k,i))
{
dp[j][k+a[i]-b[i]]=dp[j-][k]+a[i]+b[i];
//if (j==3&&k+a[i]-b[i]==57&&k==58) printf("sdfs%d\n",d[j-1][k]);
d[j][k+a[i]-b[i]]=i;
//if (j==2&&k+a[i]-b[i]==58) printf("%d\n",i);
}
}
int k,div;
for (int i=;i<=fix;i++)
if (dp[m][fix-i]!=-||dp[m][fix+i]!=-) {k=i;break;}
//printf("%d\n",k);
div=dp[m][fix-k]>dp[m][fix+k]?(fix-k):(fix+k);
printf("Jury #%d\n",++time);
printf("Best jury has value %d for prosecution and value %d for defence:\n",(dp[m][div]+div-fix)/,(dp[m][div]-div+fix)/);
int r=div;
for (int i=;i<=m;i++)
{
id[i]=d[m-i+][r];
r-=a[id[i]]-b[id[i]];
}
sort(id+,id++m);
for (int i=;i<=m;i++) printf(" %d",id[i]);
printf("\n\n");
}
return ;
}

[Poj 1015] Jury Compromise 解题报告 (完全背包)的更多相关文章

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

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

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

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

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

  4. POJ 1015 Jury Compromise(双塔dp)

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

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

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

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

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

  7. POJ 1015 Jury Compromise dp分组

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

  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的写法是错的.亲测,背包做法无误. dp[i][j][k]表示前i个物品,选择j个,差值为k的情况下获得的最大总和 dp[i][j][k]=max ...

随机推荐

  1. 数据库联表统计查询 Group by & INNER JOIN

    原数据表 视频信息表  tab_video_info 播放记录表  tab_play_record 需求 统计播放量(已经开始播放)最多的前20个视频: SELECT a.video_id, SUM( ...

  2. HDU 1709

    MB,一开始就想到是不是只要加上一个不选择砝码的情况,但一直没动手做,因为看了看网上了,觉得总有点复杂,认为自己想错了.... 相信自己 #include <iostream> #incl ...

  3. string 简单实现

    namespace ss{ class string { friend ostream& operator <<(ostream&, const string&); ...

  4. 【笨木头Lua专栏】基础补充02:函数的几个特别之处

    没想到距离上一篇基础补充已经过了1年多了,近期准备捡回Lua,把基础都补补,今天来聊聊Lua的函数吧~ 0.环境 我突然对Lua又大感兴趣的最主要原因是,Cocos Code IDE開始浮出水面了,它 ...

  5. JAVA配置Tomcat

    1.下载tomcat,我jdk是1.8的,网上查了一下,说要安装tomcat8及以上的tomcat 尝试点击,弹出, 2.配置环境 3.安装通过cmd安装 4.点击开启服务 5.输入localhost ...

  6. zzulioj--1711--漂洋过海来看你(dfs+vector)

    1711: 漂洋过海来看你 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 89  Solved: 33 SubmitStatusWeb Board D ...

  7. Under ubuntu 12.04,install sublime text 2

    Sublime Text is an awesome text editor. If you’ve never heard of it, you should check it out right n ...

  8. Redis 安装与简单示例 <第一篇>【转】

    一.Redis的安装 Redis下载地址如下:https://github.com/dmajkic/redis/downloads 解压后根据自己机器的实际情况选择32位或者64位.下载解压后图片如下 ...

  9. Kali linux 2016.2 的 plyload模块之meterpreter plyload详解

    不多说,直接上干货! 前期博客 Kali linux 2016.2(Rolling)中的payloads模块详解 当利用成功后尝试运行一个进程,它将在系统进程列表里显示,即使在木马中尝试执行系统命令, ...

  10. Aspose office (Excel,Word,PPT),PDF 在线预览

    前文: 做个备份,拿的是试用版的 Aspose,功能见标题 代码: /// <summary> /// Aspose office (Excel,Word,PPT),PDF 在线预览 // ...