题目链接: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. POJ 2183

    模拟题 #include <iostream> #include <cstdio> #include <algorithm> using namespace std ...

  2. eclipse project文件夹下 删除不掉文件夹或者文件的解决的方法

    对于新手来说,有时操作失误就会导致eclipse文件夹中的某些子文件夹或者文件无法删除. 这种原因是,在project文件夹中(不是eclipse上显示的.是真实的物理磁盘上的)这个文件夹或者文件已经 ...

  3. 火狐访问IIS出现404,而Chrome可以正常访问

    需要在web.config中的handlers中添加如下节点,保存之后,需要重启电脑. <remove name="ExtensionlessUrlHandler-Integrated ...

  4. javascript系列-class10.DOM(下)

    1.node节点(更详细的获取(设置)页面中所有的内容)         根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:   元素是节点的别称,节点包含元素当然节点还有 ...

  5. javascript系列-class2.javascript 基本使用

    欢迎加入前端交流群来py: 转载请标明出处!     逻辑运算             一门计算机语言,编程的核心在于逻辑思想,当我们在编写程序的时候,逻辑是否通顺,是能否正确写出程序的关键,可以说如 ...

  6. BZOJ 2179 FFT模板

    思路:FFT板子题 //By SiriusRen #include <cstdio> #include <complex> using namespace std; typed ...

  7. hiho150周 - 动态规划*

    题目链接 一个n*m的迷宫由‘.’和'b'组成,从(1,1)走到(n,m),只能向右或者向下走,但遇到‘b’时才能改变方向,开始时方向向右. 问到达(n,m)至少改变几个位置上的值 /******** ...

  8. dede内链怎么优化,Dedecms内部链接优化技巧

    dede内链怎么优化,dedecms内部链接优化技巧 使用dedecms的过程中发现,可以通过dedecms的文档关键词维护功能.发表文章时候的关键词添加功能(也可以自动获取)以及核心设置里面的是否使 ...

  9. NOIp2018模拟赛四十四

    加量不加价?! 昨晚看时间变成了3.5h以为终于变成了正常难度,结果还是国家集训队作业... A题看起来很神仙,B题看上去很神仙,C题一看就知道很神仙: 结果发现B是假题,放榜后发现A也是假题,C是Y ...

  10. HDU 1796 How many integers can you find(容斥原理)

    题意 就是给出一个整数n,一个具有m个元素的数组,求出1-n中有多少个数至少能整除m数组中的一个数 (1<=n<=10^18.m<=20) 题解 这题是容斥原理基本模型. 枚举n中有 ...