1. 程式人生 > >[dp] poj 1015 Jury Compromise

[dp] poj 1015 Jury Compromise

題目連結:

Jury Compromise
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 24438 Accepted: 6352 Special Judge

Description

In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the general public. Every time a trial is set to begin, a jury has to be selected, which is done as follows. First, several people are drawn randomly from the public. For each person in this pool, defence and prosecution assign a grade from 0 to 20 indicating their preference for this person. 0 means total dislike, 20 on the other hand means that this person is considered ideally suited for the jury. 
Based on the grades of the two parties, the judge selects the jury. In order to ensure a fair trial, the tendencies of the jury to favour either defence or prosecution should be as balanced as possible. The jury therefore has to be chosen in a way that is satisfactory to both parties. 
We will now make this more precise: given a pool of n potential jurors and two values di (the defence's value) and pi (the prosecution's value) for each potential juror i, you are to select a jury of m persons. If J is a subset of {1,..., n} with m elements, then D(J ) = sum(dk) k belong to J 
and P(J) = sum(pk) k belong to J are the total values of this jury for defence and prosecution. 
For an optimal jury J , the value |D(J) - P(J)| must be minimal. If there are several jurys with minimal |D(J) - P(J)|, one which maximizes D(J) + P(J) should be selected since the jury should be as ideal as possible for both parties. 
You are to write a program that implements this jury selection process and chooses an optimal jury given a set of candidates.

Input

The input file contains several jury selection rounds. Each round starts with a line containing two integers n and m. n is the number of candidates and m the number of jury members. 
These values will satisfy 1<=n<=200, 1<=m<=20 and of course m<=n. The following n lines contain the two integers pi and di for i = 1,...,n. A blank line separates each round from the next. 
The file ends with a round that has n = m = 0.

Output

For each round output a line containing the number of the jury selection round ('Jury #1', 'Jury #2', etc.). 
On the next line print the values D(J ) and P (J ) of your jury as shown below and on another line print the numbers of the m chosen candidates in ascending order. Output a blank before each individual candidate number. 
Output an empty line after each test case.

Sample Input

4 2 
1 2 
2 3 
4 1 
6 2 
0 0 

Sample Output

Jury #1 
Best jury has value 6 for prosecution and value 4 for defence: 
 2 3 

Hint

If your solution is based on an inefficient algorithm, it may not execute in the allotted time.

Source


題目意思:

有n個人,每個人有個d值和p值,求選出m個人,使得|sum(d)-sum(p)|最小,如果最小值相同,則選擇|sum(d)+sum(p)|較大的。輸出選出的人。

n<=200 d,p<20 m<=20

解題思路:

dp,實際上就是一個揹包。

|sum(d)-sum(p)|最小,實際上就是找能湊成的最靠近0的.由於-20=<d-p<=20,所以把每個d-p都加上20,變成非負的整數。然後算出最靠近20*m的就是滿足要求的最小的。

dp[i][j]:表示當sum(d)-sum(p)為i,且有j個人時,能否湊成。儲存一個add[i][j]:表示這j個人的sum(d)+sum(p)

最後在20*m附近找.

程式碼:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 8100

int dp[Maxn][25],add[Maxn][25];
int savea[220],saveb[220];
vector<int>re[Maxn][25];
int n,m;


int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   int ca=0;

   while(scanf("%d%d",&n,&m)&&n+m)
   {
       for(int i=1;i<=n;i++)
           scanf("%d%d",&savea[i],&saveb[i]);
       memset(dp,0,sizeof(dp));
       memset(add,0,sizeof(add));
       dp[0][0]=1;

       int lim=20*n*2;
       for(int i=0;i<=lim;i++)
            for(int j=0;j<=m;j++)
                re[i][j].clear();

       for(int i=1;i<=n;i++)
       {
           int temp=savea[i]-saveb[i]+20;

           for(int j=lim;j>=temp;j--)
           {
               for(int k=m;k>=1;k--)
               {
                   if(dp[j-temp][k-1])
                   {
                       int te=add[j-temp][k-1]+savea[i]+saveb[i];
                       if(!dp[j][k])
                       {
                           add[j][k]=te;
                           re[j][k]=re[j-temp][k-1];
                           re[j][k].push_back(i);
                           dp[j][k]=1;
                       }
                       else if(te>add[j][k])
                       {
                           add[j][k]=te;
                           re[j][k]=re[j-temp][k-1];
                           re[j][k].push_back(i);
                       }
                   }
               }
           }
       }
       int ansa,ansb,a;

       int p=0,pp=20*m;
       int k=m;

       while(!dp[pp+p][k]&&!dp[pp-p][k])
           p++;
       if(!dp[pp+p][k])
       {
           ansa=abs((pp-p+add[pp-p][k]-20*m))/2;
           ansb=(add[pp-p][k]-pp+p+20*m)/2;
           a=pp-p;
           //printf("Best jury has value %d for prosecution and value %d for defence:\n",ansa,)
       }
       else if(!dp[pp-p][k])
       {
           ansa=abs((pp+p+add[pp+p][k]-20*m))/2;
           ansb=(add[pp+p][k]-pp-p+20*m)/2;
           a=pp+p;
       }
       else
       {
           if(add[pp+p][k]>add[pp-p][k])
           {
               ansa=abs((pp+p+add[pp+p][k]-20*m))/2;
               ansb=(add[pp+p][k]-pp-p+20*m)/2;
               a=pp+p;
           }
           else
           {
               ansa=abs((pp-p+add[pp-p][k]-20*m))/2;
               ansb=(add[pp-p][k]-pp+p+20*m)/2;
               a=pp-p;
           }
       }
       printf("Jury #%d\n",++ca);
       printf("Best jury has value %d for prosecution and value %d for defence:\n",ansa,ansb);
       for(int i=0;i<re[a][k].size();i++)
            printf(" %d",re[a][k][i]);
       printf("\n\n");
   }
   return 0;
}




相關推薦

[dp] poj 1015 Jury Compromise

題目連結: Jury Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24438 Accepted: 6352 Special Judge Description

POJ - 1015 Jury Compromise

fff rose inf names .com mat const light ans input: 4 2 1 2 2 3 4 1 6 2 0 0    output: Jury #1 Best jury has value 6 for prose

POJ 1015 簡單dp 對映 路徑

要求:n個人,每個人有兩個指標p和d。選m個人,這些人的p之和為sump,d之和為sumd。求最小的abs(sumd-sump),若最小的abs(sumd-sump)不唯一,則最大的sumd+sump為滿足題意解,輸出sump和sumd,升序輸出這m個人序號。 方法:dp 1.dp[i][j

POJ1015-Jury Compromise 以及 uva 323正確二維DP解法

這道題網上的二維DP標準演算法是完全錯誤的,花了我好幾天去思考,後來通過一點點模擬總算找到了錯誤,且聽我慢慢道來,至於錯誤程式網上有很多,可以去搜索我就不給連結了。 還有,UVA323這道題加強過資料,這才能驗證是否是正確的程式。 網上廣泛流傳的二維DP思路是已經已經選擇

數位DP POJ

side ios i++ eight sample line search tput namespace Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submission

POJ 1015 -- 陪審團人選

-a set best special 存在 none 註意 一個 ostream 陪審團人選 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29543 A

【POJ1015】Jury compromise 多個費用的背包

ise best parse || inline memory 最大 tor 題目 這是一道比較綜合的動態規劃問題。 首先,根據題目中的從N個人中選出M個人,並且要使得某個目標函數最優,可以想到是背包問題,且因為要取出M個人,人數也應該作為背包體積的一個維度。 其次,要求輸

樹形dp poj-2342與codeforces Round #525(Div 2)E

poj-2342 題目連結:http://poj.org/problem?id=2342 很簡單的樹形dp,狀態方程是: dp[i][1]+=dp[j][0] (在選擇 i 的情況,j 是 i 的下屬 ) dp[i][0]+=max(dp[j][0],dp[j][1]) (

dp: POJ 3046 Ant Counting

Description Bessie was poking around the ant hill one day watching the ants march to and fro while gathering food. She realized th

矩陣快速冪應用於概率DP POJ 3744

第一次構造了2*2的矩陣,不成功: matrix[2][2]={p,1.0,1.0-p,0} #include<cctype> #include<cmath> #include<cstdio> #include<cstring>

簡單樹形dp-poj-1655-Balancing Act

題目連結: 題目意思: 給一棵樹,求去掉一個節點,形成的多棵樹中節點數的最大值最小。 解題思路: 簡單樹形dp. dp[i]表示兒子中節點數最多的分支節點數。 sum[i]表示i為根的子樹節點總數。 第一遍dfs求出dp和sum,第二遍dfs列舉去掉的節點,max(dp[

圖論+dp poj 1112 Team Them Up!

題目連結: 題目大意: 有編號為1~n的n個人,給出每個人認識的人的編號,注意A認識B,B不一定認識A,讓你將所有的人分成兩組,要求每組的人相互認識,且兩組的人數要儘可能的接近。 求出每組的人的編號。 解題思路: 圖論+揹包(輸出物品)。 相互認識的關係不好確定分組,如果

POJ1015 Jury Compromise

sin sca pac 需要 循環 block scanf rom i++ POJ1015 Jury Compromise 我們可以將每個候選人的辯控差作為該物品的體積之一,把辯控和作為物品的價值。 因為評價差的總分值最大可能就只有[-400,400],所以我們整體加上2

動態規劃之Jury Compromise

Jury Compromise In Frobnia, a far-awaycountry, the verdicts in court trials are determined by a jury consisting ofmembers of the genera

Poj 1015

轉載自 優YoU   http://blog.csdn.net/lyy289065406/article/details/6671105 大致題意: 在遙遠的國家佛羅布尼亞,嫌犯是否有罪,須由陪審團決定。陪審團是由法官從公眾中挑選的。先隨機挑選n 個人作為陪審團的候選

poj:1850 Code(組合數學?數位dp!)

urn font log strlen adc i++ 分享 依次 one   題目大意:字符的字典序依次遞增才是合法的字符串,將字符串依次標號如:a-1 b-2 ... z-26 ab-27 bc-52。   為什麽題解都是組合數學的...我覺得數位dp很好寫啊(逃   

POJ 2533 Longest Ordered Subsequence DP

tro wid element ogr cst ++ max integer article Longest Ordered Subsequence Time Limit: 2000MS Memory Limit: 65536K Total Submi

poj 3252 Round Numbers 數位dp

變量 數量 div read sdn .net blog air ble 題目鏈接: http://poj.org/problem?id=3252 題意: 求一段區間中二進制中0的數量要不能少於1的數量的數的個數。 思路: 套路 都是套路 http://blog.csdn

POJ 1260-Pearls(DP

ctype set lowest cas str pri font mount scan Pearls Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7465 Accepted

POJ 3254 Corn Fields (狀壓DP)

sign inline con cout ont tor const put 方式 題意:給定一個n*m的01矩陣,然後求有多少種方式,在1上並且1不相鄰。 析:一個簡單的狀壓DP,dp[i][s] 表示 第 i 行狀態為 s 時有多少種,然後只要處理不相鄰就行了,比賽進位