pku1015Jury Compromise-最小差最大和dp

来源:互联网 发布:怪物猎人p3武器数据库 编辑:程序博客网 时间:2024/06/05 14:45

pku1015Jury Compromise


n组数字,每组两个数字 d 和 p,要求从中选出m组,使(m个d的和)与(m个p的和)之差最大,如果有种情况的差值相同,取所有d,p总和最大的那种情况。


参考



#include<iostream>#include<string.h>#include<algorithm>using namespace std;int dp[21][801],path[21][801],v[201],s[201],list[21];bool select(int j,int k,int i){while(j>0 && path[j][k]!=i){k-=v[ path[j][k] ];j--;}return j?1:0;}int main(){int T=1,n,m,i,j,k,d,p,fix;while(scanf("%d%d",&n,&m),n+m){memset(dp,-1,sizeof(dp));memset(path,0,sizeof(path));fix=m*20;dp[0][fix]=0;for(i=1;i<=n;i++){scanf("%d%d",&d,&p);v[i]=d-p;s[i]=d+p;}for(j=1;j<=m;j++)for(k=0;k<=2*fix;k++)if(dp[j-1][k]>=0)for(i=1;i<=n;i++)if(dp[j][k+v[i]]<dp[j-1][k]+s[i])if(!select(j-1,k,i)){dp[j][k+v[i]]=dp[j-1][k]+s[i];path[j][k+v[i]]=i;}//for(i=1;i<=m;i++)printf("!%d ",list[i]);printf("\npath\n");for(k=0;k<=fix;k++)if(dp[m][fix-k]>=0||dp[m][fix+k]>=0)break;d=dp[m][fix-k]>dp[m][fix+k]?fix-k:fix+k;for(p=d,i=1;i<=m;i++){list[i]=path[m-i+1][p];p-=v[list[i]];}sort(list+1,list+m+1);printf("Jury #%d\n",T++);printf("Best jury has value %d for prosecution and value %d for defence:\n",(dp[m][d]+d-fix)/2,(dp[m][d]-d+fix)/2);for(i=1;i<=m;i++)printf(" %d",list[i]);printf("\n\n");}return 0;}/*4 2 1 2 2 3 4 1 6 2 Jury #1 Best jury has value 6 for prosecution and value 4 for defence:  2 3 */





原创粉丝点击