dp[i][j]记录由i个人组成,差值为j的陪审团的最大和
注意不能只保存一个绝对值,要两个值都保存。所以要把所有差都加上400,即把dp[0][400]初始为0,其他都初始为-1
要维护的有:
dp[i][j]状态中已经有的人vis[i][j][k]
G[i][j]是组成dp[i][j]的所有人的集合
o[i][j],d[i][j]是辩方和,控方和
代码:
// // main.cpp // 1015 Jury Compromise // // Created by Baoli1100 on 15/4/11. // Copyright (c) 2015年 Baoli1100. All rights reserved. // #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> using namespace std; int dp[25][900]; int M,N; int a[205]; int c[205]; int o[25][900]; int d[25][900]; int x[205]; int y[205]; bool vis[25][900][205]; vector<int> G[25][900]; int main(){ int kase=1; while(~scanf("%d%d",&N,&M)){ if(!N&&!M) break; memset(dp,-1,sizeof(dp)); memset(o,0,sizeof(o)); memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); for(int i=0;i<=20;i++){ for(int j=0;j<=800;j++){ G[i][j].clear(); } } for(int i=0;i<N;i++){ scanf("%d%d",&x[i],&y[i]); a[i]=x[i]-y[i]; c[i]=x[i]+y[i]; } dp[0][400]=0; for(int j=0;j<M;j++){ for(int k=0;k<=800;k++){ if(dp[j][k]!=-1){ for(int i=0;i<N;i++){ if(!vis[j][k][i]){ int num=k+a[i]; if(dp[j][k]+c[i]>=dp[j+1][num]){ dp[j+1][num]=dp[j][k]+c[i]; G[j+1][num].clear(); for(int l=0;l<N;l++) vis[j+1][num][l]=0; for(int l=0;l<G[j][k].size();l++){ G[j+1][num].push_back(G[j][k][l]); vis[j+1][num][G[j][k][l]]=1; } G[j+1][num].push_back(i); vis[j+1][num][i]=1; o[j+1][num]=o[j][k]+x[i]; d[j+1][num]=d[j][k]+y[i]; } } } } } } printf("Jury #%d\n",kase++); for(int i=0;i<=400;i++){ if(dp[M][400+i]!=-1||dp[M][400-i]!=-1){ if(dp[M][400+i]>dp[M][400-i]){ printf("Best jury has value %d for prosecution and value %d for defence:\n",o[M][400+i],d[M][400+i]); sort(G[M][400+i].begin(),G[M][400+i].end()); for(int j=0;j<G[M][400+i].size();j++){ printf(" %d",G[M][400+i][j]+1); } printf("\n"); break; } else{ printf("Best jury has value %d for prosecution and value %d for defence:\n",o[M][400-i],d[M][400-i]); sort(G[M][400-i].begin(),G[M][400-i].end()); for(int j=0;j<G[M][400-i].size();j++){ printf(" %d",G[M][400-i][j]+1); } printf("\n"); break; } } } } return 0; }