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;
}
本文介绍了一种使用动态规划解决陪审团妥协问题的方法。通过维护多个状态,如陪审团成员集合、辩方和控方的得分等,来找出最佳陪审团组合。代码实现详细展示了算法流程。
298

被折叠的 条评论
为什么被折叠?



