UVA323 Jury Compromise

思路:背包类DP

提交:3次

错因:没有注意得分的上下界导致 RE 显示 WA

题解:

我们很容易的想到把两种分数做一个差,来尽量背到 \(0\)
那最大化总分呢?这时我们可以用两种分数的和作为物品的价值。
记录方案呢?每个状态开一个 vector ,来记录转移的物品。(今天新学)(虽然空间大但是方便写)

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int N=810;
int T,n,m,cas,D,f[25][N],v[N/4],w[N/4];
vector <int> h[25][N];
inline void main() {
	while(~scanf("%d%d",&n,&m)&&n) { memset(f,-1,sizeof f);
		for(R i=1;i<=m;++i) for(R j=0;j<N;++j) h[i][j].clear(); D=20*m,f[0][D]=0;
		for(R i=1,a,b;i<=n;++i) a=g(),b=g(),v[i]=a-b,w[i]=a+b;
		for(R i=1;i<=n;++i) for(R j=m;j;--j) for(R k=max(0,v[i]),lim=2*D+min(0,v[i]);k<=lim;++k) //之前就是 k 的上界写错了。
			if(~f[j-1][k-v[i]]) if(f[j-1][k-v[i]]+w[i]>f[j][k]) 
				f[j][k]=f[j-1][k-v[i]]+w[i],h[j][k]=h[j-1][k-v[i]],h[j][k].push_back(i);
		R sum; for(sum=0;sum<=D;++sum) if((~f[m][D+sum])||(~f[m][D-sum])) break;
		R ans=f[m][D+sum]>f[m][D-sum]?D+sum:D-sum;
		R anss=f[m][ans]; R ans1=(anss+(ans-D))/2,ans2=(anss-(ans-D))/2;
		printf("Jury #%d\n",++T);
	  printf("Best jury has value %d for prosecution and value %d for defence:\n",ans1,ans2);
	  for(R i=0;i<m;++i) printf(" %d",h[m][ans][i]); printf("\n\n");
	}
}
} signed main() {Luitaryi::main(); return 0;}

2019.09.18
58

posted @ 2019-09-18 21:54  LuitaryiJack  阅读(222)  评论(0编辑  收藏  举报