zoukankan      html  css  js  c++  java
  • UVA 323 Jury Compromise

    https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=259

    题目

    在一个遥远的国家,法庭上审判结果需要陪审团给出,陪审团是从大众中选出来的。首先从社会中随机抽取n个人,参与诉讼的控方和辩方会对每个人打分,0表示完全不赞同,20表示完全赞同。法官为了公平,会尽量均衡地从这n个人中选择m个人,使控方和辩方都比较满意。具体是:将选出的m个人的控方打分加起来,得到a,将选出的m个人的检方打分加起来,得到b,计算$leftlvert a-b ight vert$。选择$leftlvert a-b ight vert$最小的m人作为陪审团,如果同时存在多种选择,选择a+b最大的作为陪审团。写出程序,模拟选择的过程,并输出选择的方案。

    $1leqslant nleqslant 200, 1leqslant mleqslant 20$

    题解

    设$dp[a][i][j]$为前$a$个人选择了i个人,差为j

    $dp[a][i][j]=dp[a-1][i][j]$

    $dp[a][i][j]=dp[a-1][i-1][j-(p-q)]+a[p]+a[q]$

    计算值的时候可以滚动优化掉第一维,转移的时候需要完整记录

    AC代码

    #include<cstdio>
    #include<cstring>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    int dp[27][807];
    int pj[207][27][807], pa[207][27][807];
    bool can[27][807];
    int p[207], d[207];
    int n,m;
    void prn(int a, int i, int j) {
    	if(i==0) return;
    	int ka = pa[a][i][j];
    	prn(ka-1, i-1, pj[ka][i][j]);
    	printf(" %d", ka);
    }
    int main() {
    	int kase=0;
    	while(~scanf("%d%d", &n, &m) && n) {
    	REPE(i,1,n) {
    		scanf("%d%d", &p[i], &d[i]);
    	}
    	memset(can,0,sizeof can), memset(dp,-1,sizeof dp);
    	dp[0][400]=0, can[0][400]=1;
    	//dp[a][i][j] = dp[a-1][i][j]
    	//dp[a][i][j] = dp[a-1][i-1][j-(p[i]-d[i])]
    	REPE(a,1,n) PERE(i,m,1) {
    		REPE(j,0,800) {
    			int pv=j-(p[a]-d[a]);
    			pa[a][i][j]=pa[a-1][i][j];
    			pj[a][i][j]=pj[a-1][i][j];
    			if(pv<=800 && pv>=0 && can[i-1][pv]) {
    				int nd=dp[i-1][pv]+p[a]+d[a];
    				if(nd>dp[i][j]) {
    					dp[i][j]=nd;
    					can[i][j]=1;
    					pj[a][i][j]=pv;
    					pa[a][i][j]=a;
    				}
    			}
    		}
    	}
    	int ans=-1, ch=-1;
    	REPE(dj,0,400) {
    		if(can[m][dj+400] && dp[m][dj+400]>ans) {
    			ans=dp[m][dj+400];
    			ch=dj+400;
    		}
    		if(can[m][400-dj] && dp[m][400-dj]>ans) {
    			ans=dp[m][400-dj];
    			ch=400-dj;
    		}
    		if(ch>=0) break;
    	}
    	printf("Jury #%d
    ", ++kase);
    	printf("Best jury has value %d for prosecution and value %d for defence:
    ", (ans+ch-400)/2, (ans-ch+400)/2);
    	prn(n, m, ch);
    	putchar('
    ');
    	putchar('
    ');
    	}
    }
    
  • 相关阅读:
    python3 多线程的基本用法
    ASP.NET MVC下的四种验证编程方式
    漫步ASP.NET MVC的处理管线
    asp.net mvc源码分析-Action篇 IModelBinder
    在 Asp.NET MVC 中使用 SignalR 实现推送功能
    说说Python 中的文件操作 和 目录操作
    Python 用 os.walk 遍历目录
    我来说说MVC过滤器
    学习Python必须要知道的常用模块
    Python中的并发编程
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12426756.html
Copyright © 2011-2022 走看看