## 1015 Jury Compromise

```#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rg register
#define go(i,a,b) for(rg int i=a;i<=b;i++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int n,m,dp[25][802];
int p[202],d[202],S[202],V[202];
int tag[25][802];
//tag[i][j]表示选了i个人分数为j时第i个人的编号
bool check(int a,int b,int c){//判断c是否被选过
while(a>0&&c!=tag[a][b]){
b-=V[tag[a][b]];a--;
}
return a;
}
int main(){
int num=0;
while(scanf("%d%d",&n,&m)){
if(n==0&&m==0) break;
go(i,1,n){
scanf("%d%d",&p[i],&d[i]);
S[i]=p[i]+d[i];
V[i]=p[i]-d[i];
}
memset(dp,-1,sizeof(dp));
//dp[i][j]表示选了i个人使分数差值为j的最大和，如不存在则为-1
memset(tag,0,sizeof(tag));
int start=20*m;
dp[0][start]=0;//相当于dp[0][0]
go(i,1,m) go(j,0,2*start)
if(dp[i-1][j]!=-1)
go(k,1,n)
if(!check(i-1,j,k)&&dp[i][j+V[k]]<dp[i-1][j]+S[k]){
dp[i][j+V[k]]=dp[i-1][j]+S[k];
tag[i][j+V[k]]=k;
}
int j;
for(j=0;j<=start;j++)
if(dp[m][start-j]!=-1||dp[m][start+j]!=-1) break;
int sum=dp[m][start-j]>dp[m][start+j]?start-j:start+j;
int P=(dp[m][sum]+sum-start)/2,D=(dp[m][sum]-sum+start)/2;
printf("Jury #%d\n",++num);
printf("Best jury has value %d for prosecution and value %d for defence:\n",P,D);
int res[25];
for(rg int i=0,j=m,k=sum;i<m;i++){
res[i]=tag[j][k];
k-=V[tag[j][k]];
j--;
}
sort(res,res+m);
go(i,0,m-1) printf(" %d",res[i]);
puts("");puts("");
}
return 0;
}```