• poj1015 Jury Compromise


    poj1015 Jury Compromise

    https://vjudge.net/problem/POJ-1015

    /*
        直接上翻译吧
        这是一道动态规划,请教了wmy学姐之后感觉有思路了
        感觉和二维费用背包有点像
        需要考虑的方面有 控辩和,控辩差,人数,组合路径
        其中路径可以另外设一个path[i][j]表示使得[i][j]这个状态最优的上一个是谁
        dp[i][j]=k表示选了i个人,总的控辩差是j的总控辩和是多少
        最后找答案时只需找最接近需求值的j所对应的路径以及总控辩和差
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 205
    #define maxm 25
    int dp[maxm][maxn*10],path[maxm][maxn*10],n,m,a[maxn],b[maxn],Ans[maxn];
    bool vis[220];
    void up(int i,int j){
        memset(vis,0,sizeof(vis));
        while(path[i][j]!=-1){
            int k=path[i][j];
            vis[k]=1;
            i--;j-=a[k]-b[k];
        }
    }
    void update(int i,int j,int k){
        int x=a[k]+b[k];
        int y=a[k]-b[k];
        if(dp[i+1][j+y]==-1||(dp[i+1][j+y]<dp[i][j]+x)){
            dp[i+1][j+y]=dp[i][j]+x;
            path[i+1][j+y]=k;
        }
    }
    int main(){
        int T=0;
        while(1){
            memset(dp,-1,sizeof(dp));
            memset(path,-1,sizeof(path));
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            memset(Ans,0,sizeof(Ans));
            scanf("%d%d",&n,&m);
            if(n==0&&m==0)return 0;
            T++;
            printf("Jury #%d 
    ",T);
            for(int i=0;i<n;i++)scanf("%d%d",&a[i],&b[i]);
            int w=20*m;
            dp[0][w]=0;
            for(int i=0;i<m;i++)for(int j=0;j<=w*2;j++)
                if(dp[i][j]!=-1){
                    up(i,j);
                    for(int k=0;k<n;k++)
                        if(!vis[k])update(i,j,k);
                }
            int d1=-1,d2=-1,ans;
            for(int i=0;i<=w;i++)
                if(dp[m][w+i]!=-1){d1=i;break;}
            for(int i=0;i<=w;i++)
                if(dp[m][w-i]!=-1){d2=i;break;}
            if(d1==-1||(d1>d2&&d2!=-1))ans=w-d2;
            else if(d2==-1||(d1<d2&&d1!=-1))ans=w+d1;
            else if(d1==d2&&dp[m][w+d1]>dp[m][w-d2])ans=w+d1;
            else ans=w-d2;
            int x=dp[m][ans],y=ans-w; 
            int ans1=(x+y)/2,ans2=(x-y)/2;
            printf("Best jury has value %d for prosecution and value %d for defence:
    ", ans1, ans2);
            int cnt=0;
            int u=m,v=ans;
            while(path[u][v]!=-1){
                int k=path[u][v];
                Ans[cnt++]=k;
                u--;v-=a[k]-b[k];
            }
            sort(Ans,Ans+cnt);
            for (int i = 0; i < cnt; i++)
           printf(" %d", Ans[i] + 1);
           putchar('
    ');
       putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    【MongoDB初识】-结合C#简单使用,驱动2.x
    【NuGet】打包上传一条龙服务
    【NuGet】搭建自己团队或公司的NuGet
    【MongoDB初识】-其他操作
    【MongoDB初识】-条件操作符
    【MongoDB初识】-增删改
    【MongoDB初识】-安装篇
    【面试题】-100盏灯
    【微信开发】一获取用户授权(静默授权方式)
    XML序列化及反序列化
  • 原文地址:https://www.cnblogs.com/thmyl/p/6978129.html
Copyright © 2020-2023  润新知