转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6671105
题目大意:选出的m 个人,必须满足辩方总分D和控方总分P的差的绝对值|D-P|最小。如果有多种选择方案的 |D-P| 值相同,那么选辩控双方总分之和D+P最大的方案即可。
其实一开始并没有做对,参考了一个大神的博客,思路很好想,但是怎么推我还是不太明白。
/*
dp[i][j] i个人,差值为j的和
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
int dp[50][1000],path[50][1000][30];
int n,m,i,j,k,cas,fix,sumd,sump,temp,t;
int d[300],p[300],plu[300],subs[300];
int main(){
while( scanf("%d%d",&n,&m) && n && m){
printf( "Jury #%d\n", ++cas);
for( i=0; i<n; i++){
scanf( "%d%d", &d[i], &p[i]);
plu[i] = d[i] + p[i];
subs[i] = d[i] - p[i];
}
fix = 20*m;
memset(dp,-1,sizeof(dp)); memset(path,0,sizeof(path));
dp[0][fix] = 0;
for(k=0; k<n; k++)
for(i=m-1; i>=0; i--)
for(j=0; j<=fix*2; j++)
if(dp[i][j]>=0){
if(dp[i+1][j+subs[k]]<dp[i][j]+plu[k]){
dp[i+1][j+subs[k]]=dp[i][j]+plu[k];
for(t=0; t<i; t++) path[i+1][j+subs[k]][t]=path[i][j][t];
path[i+1][j+subs[k]][t]=k;
}
}
for(i = 0; dp[m][fix+i] == -1 && dp[m][fix-i] == -1; i++);
temp = dp[m][fix+i] > dp[m][fix-i] ? i : -i;
sumd = (dp[m][fix+temp]+temp)/2;
sump = (dp[m][fix+temp]-temp)/2;
printf("Best jury has value %d for prosecution and value %d for defence:\n", sumd, sump);
for(i=0; i<m; i++) printf(" %d",path[m][fix+temp][i]+1);
printf("\n");
}
}
听说写博客能加深对题目的理解,第一次写,希望能成为对我的激励吧