POJ 015 Jury Compromise

题意:从n个人中选出m个,每个人有固定的p值,d值,要求使m个人的p总和和d总和的差的绝对值最小,若有多解则取两者和最大的。

分析:dp[i][j]表示在选m个人中的第i个人的时候使所有已选中的人的b,p差为j时,所能获得的b,p最大和。

         dp[i + 1][j + b[k] - p[k]] = dp[i][j] + b[k] + p[k];(要求k之前没有选过,要查看[i][j]的完整路径,确保无k)

         填写完成后,观察找到最小差值,最大和。知道和差自然可以求出总的p,d。

View Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define clr(x)memset(x,0,sizeof(x))
#define max(a,b)(a)>(b)?(a):(b)
int hu[31][805],dp[31][805];
int cmp(const void*p1,const void*p2)
{   return *(int*)p1-*(int*)p2;    }
struct node
{
    int b,p;
}q[205];
int n,m;
void solve()
{
    int i,j,k;
    int x,s;
    for(i=0;i<m;i++)
        for(j=0;j<=800;j++)
            for(k=1;k<=n;k++)
            {
                if(dp[i][j]<0) break;
                if(dp[i+1][j+q[k].b-q[k].p]<dp[i][j]+q[k].b+q[k].p)
                {   
                    s=j;
                    for(x=i;x>0&&hu[x][s]!=k;x--)
                        s-=q[hu[x][s]].b-q[hu[x][s]].p;
                    if(x==0)
                    {
                        dp[i+1][j+q[k].b-q[k].p]=dp[i][j]+q[k].b+q[k].p;
                        hu[i+1][j+q[k].b-q[k].p]=k;
                    }
                }
            }
}
int res[205];
int main()
{
    int ca=1,a,b,i,k;
    while(scanf("%d%d",&n,&m),n||m)
    {
        clr(hu);
        clr(res);
        memset(dp,0xff,sizeof(dp));
        dp[0][400]=0;
        for(i=1;i<=n;i++)
            scanf("%d%d",&q[i].b,&q[i].p);
        solve();
        for(k=0;dp[m][400+k]<0&&dp[m][400-k]<0;k++);
        int tt=dp[m][400+k]>dp[m][400-k]?400+k:400-k;
        a=b=0;
        for(i=0;i<m;i++)
        {
            res[i]=hu[m-i][tt];
            a+=q[res[i]].b;
            b+=q[res[i]].p;
            tt-=q[res[i]].b-q[res[i]].p;
        }
        qsort(res,m,sizeof(res[0]),cmp);
        printf("Jury #%d\n",ca++);
        printf("Best jury has value %d for prosecution and value %d for defence:\n",a,b);
        for(i=0;i<m;i++)
            printf(" %d",res[i]);
        printf("\n");
    }
    return 0;
}

 

posted @ 2012-07-18 19:29  'wind  阅读(214)  评论(0编辑  收藏  举报