POJ 1015 Jury Compromise

传送门:http://poj.org/problem?id=1015

 

解题思路:

实现代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN=1000;
const int INF=1<<30;
int dp[30][MAXN],Path[30][MAXN];
int D[MAXN],P[MAXN];

/*
dp[j][k]:选取第j个人(也就是总共选了j个人),其辩控差为k时,其辩方和空方的和。
为了防止k是负数,我们将k向右移动m×20
设我们选的第j个人的编号是i(1<=i<=m)
dp[j][k]=max(dp[j][k],dp[j-1][k-P[i]+D[i]]+D[i]+P[i];

Path[j][k]:选择第j个人其辩控差为k在n个人中的编号
那么第j-1选择的人编号Path[j-1][k-D[Path[j][k]]+P[Pah[j][k]]]
*/


int main(){
    int n,m;
    int iCase=0;
    while(scanf("%d%d",&n,&m)!=EOF||(n!=0&&m!=0)){
        for(int i=1;i<=n;i++)
            scanf("%d%d",&P[i],&D[i]);

        int IMAX=m*20;
        memset(dp,-1,sizeof(dp));
        memset(Path,0,sizeof(Path));

        dp[0][IMAX]=0;
        for(int j=0;j<m;j++){
                for(int k=0;k<=IMAX*2;k++){
                   if(dp[j][k]>=0){
                    for(int i=1;i<=n;i++){
                        if(dp[j][k]+D[i]+P[i]>dp[j+1][k+P[i]-D[i]]){
                            int t1=j,t2=k;
                            while(t1>0&&Path[t1][t2]!=i){
                                t2-=P[Path[t1][t2]]-D[Path[t1][t2]];
                                t1--;
                            }
                            if(t1==0){
                                dp[j+1][k+P[i]-D[i]]=dp[j][k]+D[i]+P[i];
                                Path[j+1][k-D[i]+P[i]]=i;
                            }


                        }
                   }

                   }
                }

        }

        int i=IMAX;
        int j=0;
        int k;
        while(dp[m][i-j]<0&&dp[m][i+j]<0)
            j++;
        if(dp[m][i+j]>dp[m][i-j])
            k=i+j;
        else
            k=i-j;
        printf("Jury #%d
",++iCase);
        printf("Best jury has value %d for prosecution and value %d for defence:
",(k-IMAX+dp[m][k])/2,(dp[m][k]-k+IMAX)/2);

        int Answer[MAXN];
        for(i=0;i<m;i++){
            Answer[i]=Path[m-i][k];
            k-=P[Answer[i]]-D[Answer[i]];
        }
        sort(Answer,Answer+m);
        for(i=0;i<m;i++)
            printf(" %d",Answer[i]);
        printf("

");

    }
}
自己选的路,跪着也要把它走完------ACM坑
原文地址:https://www.cnblogs.com/IKnowYou0/p/6627010.html