POJ 1015 Jury Compromise(DP)

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;
}


你可能感兴趣的:(POJ 1015 Jury Compromise(DP))