洛谷传送门

$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. vb.net机房收费系统——存储过程

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/xdd19910505/article/details/35574125 一.使用背景         ...

  2. 洛谷P3366 【模板】最小生成树(kuskal)

    #include<bits/stdc++.h> using namespace std; ; ; struct node{ int cnt,fa; }f[maxn]; inline voi ...

  3. day5_python之subprocess模块

    subprocess作用:用来执行系统命令它会开启一个子进程,通过子进程去执行一些命令 读取正确的命令执行结果,如果没有指定把结果输出到哪里,默认打印到屏幕上 #subprocess.Popen(r' ...

  4. Lists and keys

    function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) = ...

  5. Refs

    一.The ref callback attribute ref:reference,父组件引用子组件 组件并不是真实的 DOM节点,而是存在于内存之中的一种数据结构,叫做虚拟DOM.只有当它插入文档 ...

  6. 2016年开源软件排名TOP50,最受IT公司欢迎的50款开源软件

    2016年开源软件排名TOP50,最受IT公司欢迎的50款开源软件 过去十年间,许多科技公司已开始畅怀拥抱开源.许多公司使用开源工具来运行自己的 IT 基础设施和网站,一些提供与开源工具相关的产品和服 ...

  7. hdu 1535 Invitation Cards(spfa)

    Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  8. iptablesIP规则的保存与恢复

    iptables-save把规则保存到文件中,再由目录rc.d下的脚本(/etc/rc.d/init.d/iptables)自动装载 使用命令iptables-save来保存规则.一般用 iptabl ...

  9. WOE:信用评分卡模型中的变量离散化方法(生存分析)

    WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...

  10. java StringBuffer 与 StringBuilder

    String是不可变类,一旦String对象被创建,包含在对象中的字符序列是不可变的,直到对象被销毁: StringBuffer 与 StringBuilder对象则是可变的! 举例说明这两个的好处: ...