第 i个人的得分分别记为 a[i] 和 b[i]
m个人必须满足:辩方总分S(a) 和控方总分 S(b) 的差的绝对值最小
如果选择方法不唯一,那么再从中选择辨控双方总分之和最大的方案。
求最终的陪审团获得的辩方总分 D 控方总分 P, 以及陪审团人选的编号
吧这个绝对值的差的和作为状态
f[ i ] [j ] [ c] =min(f[i-1][j][c], f[i-1][j-1][ c-a[i]+b[i] ] +a[i]+b[i]
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define D 400
int n,m,a[202],b[202];
int f[202][25][802],pre[202][25][900];
int S1,S2;
vector<int> vec;
void print(int i,int j,int k){
if(j==0) return ;
int p=pre[i][j][k];
print(p-1,j-1,k-a[p]+b[p]);
vec.push_back(p);
S1+=a[p],S2+=b[p];
}
void solve(int cas){
memset(f,-0x3f,sizeof f);f[0][0][0+D]=0;
int i,j;
for(i=1;i<=n;i++) cin>>b[i]>>a[i];
for(i=1;i<=n;i++)
for(j=m;j>=0;j--){
for(int k=-400;k<=400;k++){
f[i][j][D+k]=f[i-1][j][D+k];
pre[i][j][k+D]=pre[i-1][j][D+k];
if(k-a[i]+b[i]>=-400&&k-a[i]+b[i]<=400&&j>0){
if(f[i][j][k+D]<f[i-1][j-1][D+k-a[i]+b[i]]+a[i]+b[i])
f[i][j][D+k]=f[i-1][j-1][D+k-a[i]+b[i]]+a[i]+b[i],
pre[i][j][k+D]=i;
}
}
}
j=0;
for(i=0;i<=400;i++)
if(f[n][m][i+400]>=0&&f[n][m][i+400]>f[n][m][400-i]){
j=i+400;break;
}
else if(f[n][m][400-i]>=0){ j=400-i;break;}
vec.clear();
S1=S2=0;
print(n,m,j);
printf("Jury #%d\n",cas);
printf("Best jury has value %d for prosecution and value %d for defence:",
S2,S1);
cout<<endl;
for(i=0;i<vec.size();i++) cout<<vec[i]<<' ';
cout<<"\n\n";
}
main(){
int cas=0;
while(cin>>n>>m,n&&m)
solve(++cas);
}
浙公网安备 33010602011771号