《算法竞赛进阶指南》上将每个候选人的双方得分之差作为“物品体积”,将双方得分之和作为物品价值。 我把得分之和作为体积,得分之差作为价值。存储真实的差值,比较更新时按绝对值比较。已有数据拍不出错来,求大佬看看是代码写错了还是思路不对。谢谢QwQ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=210,M=25,K=810,INF=0x3f3f3f3f;
int ans,n,m,D,P,s[M],p[N],d[N],f[M][K],pre[N][M][K];
int main(){
int cnt=0;
while(cin>>n>>m,n&&m){
printf("Jury #%d\n",++cnt);
for(int i=1;i<=n;i++)
cin>>p[i]>>d[i];
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
for(int k=K-1;k>=d[i]+p[i];k--){
if(abs(f[j][k])>abs(f[j-1][k-p[i]-d[i]]+d[i]-p[i]))
f[j][k]=f[j-1][k-p[i]-d[i]]+d[i]-p[i];
pre[i][j][k]=f[j][k];
}
int minx=INF;
for(int i=0;i<K;i++)
if(abs(f[m][i])<=minx){
minx=abs(f[m][i]);
ans=i;
}
D=(f[m][ans]+ans)/2;
P=ans-D;
printf("Best jury has value %d for prosecution and value %d for defence:\n",P,D);
int i=n,j=m,k=ans;
while(i&&j){
if(k>=p[i]+d[i]&&pre[i][j][k]==pre[i-1][j-1][k-p[i]-d[i]]+d[i]-p[i]){
s[j]=i;
j--,k=k-p[i]-d[i];
}
i--;
}
for(int i=1;i<=m;i++)
cout<<" "<<s[i];
cout<<endl<<endl;
}
return 0;
}