洛谷传送门

$Sol$

这是一道具有多个“体积维度”的$0/1$背包问题。

把$N$个候选人看做$N$个物品,那么每个物品有如下三种体积:

1.“人数”,每个候选人的“人数”都是$1$,最终要填满容积为$M$的背包

2.“辩方得分”,$a[i]$

3.“反方得分”,$b[i]$

要求的是辩方总分$D$和控方总分$P$的差的绝对值$|D-P|$最小,如果选择方法不唯一,那么在从中选择$D+P$最大的方案

所以将$a[i]-b[i]$作为体积之一,将$a[i]+b[i]$作为该物品的价值

注意这里的$a[i]-b[i]$可能为负,所以统一加上$4000$

以考虑到第$i$个人为阶段,$f[j][k]$表示已经在前$i$个人中选择了$j$个人,此时两方的总分之差为$k$时,两方的总分最大值。

$f[j][k]=max(f[j][k],f[j-1][k-(a[i]-b[i])]+a[i]+b[i])$

由于还需要输出方案,所以再加一个数组$d[i][j][k]$表示$f[i][j][k]$的第$i$个候选人选没选,这样就记录了方案。

$Code$

 #include<iostream>
#include<cstdio>
#include<cstring>
#define Rg register
#define il inline
#define mem(a,b) memset(a,b,sizeof(a));
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i--)
using namespace std;
il int read()
{
int x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
int T,n,m,hhh=,t,ct,a[],b[],f[][],as[];
bool d[][][];
int main()
{
while()
{
n=read(),m=read();if(!n)break;
printf("Jury #%d\n",++T);
go(i,,n)a[i]=read(),b[i]=read();
mem(f,-);mem(d,);
f[][hhh]=;
go(i,,n)
yes(j,m,)
go(k,-,)
{
if(k-(a[i]-b[i])>=- && k-(a[i]-b[i])<= && f[j-][k-(a[i]-b[i])+hhh]+a[i]+b[i]>= && f[j][k+hhh]<f[j-][k-(a[i]-b[i])+hhh]+a[i]+b[i])
f[j][k+hhh]=f[j-][k-(a[i]-b[i])+hhh]+a[i]+b[i],d[i][j][k+hhh]=;
//if(f[j][k+hhh]>=0)cout<<"i:"<<i<<" j:"<<j<<" k:"<<k<<" f:"<<f[j][k+hhh]<<" d:"<<d[i][j][k+hhh]<<endl;
}
go(i,,)
{
if(f[m][hhh+i]>=){if(f[m][hhh+i]>f[m][hhh-i])t=i;else t=-i;break;}
else if(f[m][hhh-i]>=){t=-i;break;}
}
printf("Best jury has value %d for prosecution and value %d for defence:\n",(f[m][hhh+t]+t)/,(f[m][hhh+t]-t)/);
int nw=n;ct=m;
while(nw>)
{
int dd=d[nw][ct][t+hhh];
if(dd)as[ct]=nw,ct--,t-=(a[nw]-b[nw]);
nw--;
}
go(i,,m)printf(" %d",as[i]);printf("\n\n");
}
return ;
}

随机推荐

  1. LeetCode74 Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  2. SPOJ 8073 The area of the union of circles (圆并入门)

    Sphere Online Judge (SPOJ) - Problem CIRU [求圆并的若干种算法,圆并扩展算法]_AekdyCoin的空间_百度空间 参考AekdyCoin的圆并算法解释,根据 ...

  3. [***]HZOJ 跳房子

    一道非常神仙的题. 算法一:对于20%的数据: 模拟,直接走K步,时间复杂度O(K) 算法二:对于40%的数据:走M*N步内必有一个循环节.直接走,找循环节,时间复杂度O(M*N) 正解大概有两种做法 ...

  4. 分布式TensorFlow集群local server使用详解

    通过local server理解分布式TensorFlow集群的应用与实现. ​​简介 TensorFlow从0.8版本开始,支持分布式集群,并且自带了local server方便测试. Local ...

  5. lrj 9.4.1 最长上升子序列 LIS

    p275 d(i)是以Ai为结尾的最长上升子序列的长度 <算法竞赛入门经典-训练指南>p62 问题6 提供了一种优化到 O(nlogn)的方法. 文本中用g(i)表示d值为i的最小状态编号 ...

  6. 洛谷P1449 后缀表达式 题解 栈

    题目链接:https://www.luogu.org/problem/P1449 这道题目我们只需要开一个栈,每次读取到一个数的话就将这个数 push 进栈. 因为提供给我们的时候已经是一个后续序列了 ...

  7. 定位问题 vue+element-ui+easyui(兼容性)

    项目背景:靠近浏览器窗口的各个方向(左上.下.左.右)都有不同的模态框悬浮于窗口,这里针对于底部组件定位的选择(主要针对pc端垂直方向上的定位) 1.百分比:easyui的window窗口定位方式:设 ...

  8. java 泛型的上限与下限

    设置泛型对象的上限使用extends,表示参数类型只能是该类型或该类型的子类: 声明对象:类名<? extends 类> 对象名 定义类:类名<泛型标签 extends 类>{ ...

  9. linux scull 函数open 方法

    open 方法提供给驱动来做任何的初始化来准备后续的操作. 在大部分驱动中, open 应当 进行下面的工作: 检查设备特定的错误(例如设备没准备好, 或者类似的硬件错误 如果它第一次打开, 初始化设 ...

  10. P1039 大规模间谍入侵

    题目描述 爱丽丝魔法王国成立10周年,于是决定矩形国庆大阅兵. 在国庆大阅兵期间,为了防止暗黑王国的间谍乔装成平民混入,需要对每一个进城的人做检测. 因为暗黑王国的人长得和爱丽丝魔法王国的人长得很像, ...