poj 1015 Jury Compromise

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int maxn = 222;
const int oo = 1e9;

int d[222];
int p[222];
int dp[30][1000];//dp[i][j]选出i个人,d,p差为j的 d, p和最大。 
int Map[30][1000];//Map[i][j]为选出i个人,差为j的上一个选择的
int answer[30];

int main()
{
    int n, m;
    int kk = 1;
    while(scanf("%d%d", &n, &m), n+m)
    {
        memset(dp, -1, sizeof(dp));
        memset(Map, 0, sizeof(Map));
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d", &d[i], &p[i]);
        }
        int Min_dp = m*20;//为了避免差值为负,将差值加上m*20
        dp[0][Min_dp] = 0;
        for(int j=0; j<m; j++)
        {
            for(int k=0; k<=Min_dp*2; k++)
            {
                if(dp[j][k]>=0)//如果dp[j][k]存在的话,更新dp[j+1][k+d[i]-p[i]]
                for(int i=1; i<=n; i++)
                {
                    if(dp[j+1][k+d[i]-p[i]]<dp[j][k]+p[i]+d[i])
                    {
                        int t1 = j, t2 = k;
                        while(t1>0&&Map[t1][t2]!=i)
                        {
                            int fff = Map[t1][t2];
                            t2 -= d[fff]-p[fff];
                            t1--;
                        }
                        if(t1==0)
                        {
                            dp[j+1][k+d[i]-p[i]] = dp[j][k]+p[i]+d[i];
                            Map[j+1][k+d[i]-p[i]] = i;
                        }
                    }
                }
            }
        }
        int ff = Min_dp;
        int num = 0;
        while(dp[m][ff-num]<0&&dp[m][ff+num]<0)
            num++;
        int ans = dp[m][ff+num]>dp[m][ff-num]?ff+num:ff-num;

        printf("Jury #%d\n", kk++);
        printf("Best jury has value %d for prosecution and value %d for defence:\n", (dp[m][ans]+ans-ff)/2, (ff+dp[m][ans]-ans)/2);
        for(int i=m; i>=1; i--)
        {
            answer[i] = Map[i][ans];
            ans-=d[answer[i]]-p[answer[i]];
        }
        sort(answer+1, answer+m+1);
        for(int i=1; i<=m; i++)
        {
            printf(" %d", answer[i]);
        }
        printf("\n\n");
    }

    return 0;
}

 

posted @ 2016-04-11 14:02  梦中。。  阅读(128)  评论(0编辑  收藏  举报