[Poj 1015] Jury Compromise 解题报告 (完全背包)
题目链接: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 解题报告 (完全背包)的更多相关文章
- 背包系列练习及总结(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 ...
- poj 1015 Jury Compromise(背包+方案输出)
\(Jury Compromise\) \(solution:\) 这道题很有意思,它的状态设得很...奇怪.但是它的数据范围实在是太暴露了.虽然当时还是想了好久好久,出题人设了几个限制(首先要两个的 ...
- OpenJudge 2979 陪审团的人选 / Poj 1015 Jury Compromise
1.链接地址: http://bailian.openjudge.cn/practice/2979 http://poj.org/problem?id=1015 2.题目: 总Time Limit: ...
- POJ 1015 Jury Compromise(双塔dp)
Jury Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33737 Accepted: 9109 ...
- POJ 1015 Jury Compromise 2个月后重做,其实这是背包题目
http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从 ...
- poj 1015 Jury Compromise(背包变形dp)
In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...
- POJ 1015 Jury Compromise dp分组
第一次做dp分组的问题,百度的~~ http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑 ...
- 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 ...
- POJ 1015 Jury Compromise
感觉此题略难...... 背包问题.据说有一种二维DP的写法是错的.亲测,背包做法无误. dp[i][j][k]表示前i个物品,选择j个,差值为k的情况下获得的最大总和 dp[i][j][k]=max ...
随机推荐
- Tomcat example 应用信息泄漏漏洞及修复
Tomcat 是一款开源的 Web 应用服务器软件.Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不多的场合下被普遍使用,是开发和调试 JSP 程序的首选. 漏洞描述 Tomcat 在 ...
- Hadoop学习;測试;启动bug;secondary合并edits到fsimage
一个Hadoop集群拥有多个并行的计算机.用以存储和处理大规模的数据集 Hadoop强调代码向数据迁移 要执行的程序在规模上比数据小的多,更easy移动,此外通过网络移动数据比载入执行程序更花时间,这 ...
- Oracle字符乱码、数据越界訪问典型Bug分析
Oracle字符乱码.数据越界訪问典型Bug分析 前言: 作为乙方,在甲方客户那里验收阶段发现两个诡异Bug. 下面就问题来源.问题根因.解决方式.怎样避免做具体描写叙述. .且两 ...
- Systemd启动图形界面过程
1 启动命令 systemctl isolate graphical.target 2 启动过程: 文件:/etc/systemd/system/graphical.target 来自:systemd ...
- 安装MYSQL错误“conflicts with file from package mysql-libs-*” 解决方法
安装MYSQL的时候时: 错误现象: [root@localhost opt]# rpm -ivh MySQL-server-5.5.32-1.el6.x86_64.rpm Preparing... ...
- 编程与算法中的端点问题(linspace(a, b, n),endpoint)
左闭右开,[0, n) ⇒ [0, n-1],共 n 个元素: 1. 列表长与编号 列表(seq,也可以是数组等线性结构)的长度要比末尾元素的编号多 1,比如一个列表内含有 5 个元素,最后一个元素的 ...
- 92.bower 需要git
转自:https://blog.csdn.net/chenleismr/article/details/50458496Bower 是基于 Git 之上的包管理工具,它提供的包其源头都是一个 Git ...
- Linux就该这么学 20181004(第六章磁盘管理)
参考链接https://www.linuxprobe.com/ /boot 开机锁需要文件-内核.开机菜单以及所需配置文件 /dev 以文件形式存放的任何设备与接口 /etc 配置文件 /home 用 ...
- 正睿NOIP赠送附加赛1
T1:math 题目链接: http://zhengruioi.com/contest/156/problem/471 题解: 先讲讲我的乱搞做法.对于前面70%,我跑了背包.因为背包有后效性...我 ...
- latex简历遇到的问题
博一时候简历就没弄出来,现在又要用了,于是找出当初的模板.发现问题在于编码. \XeTeXinputencoding "GBK" \XeTeXdefaultencoding &qu ...