陪審團問題

 

問題描述:

問題描述
在遙遠的國家佛羅布尼亞,嫌犯是否有罪,須由陪審團決定。陪審團是由法官從公衆中
挑選的。先隨機挑選n 個人作爲陪審團的候選人,然後再從這n 個人中選m 人組成陪審團。
選m 人的辦法是:
控方和辯方會根據對候選人的喜歡程度,給所有候選人打分,分值從0 到20。爲了公
平起見,法官選出陪審團的原則是:選出的m 個人,必須滿足辯方總分和控方總分的差的
絕對值最小。如果有多種選擇方案的辯方總分和控方總分的之差的絕對值相同,那麼選辯控
雙方總分之和最大的方案即可。最終選出的方案稱爲陪審團方案。
輸入數據
輸入包含多組數據。每組數據的第一行是兩個整數n 和m,n 是候選人數目,m 是陪審
團人數。注意,1<=n<=200, 1<=m<=20 而且 m<=n。接下來的n 行,每行表示一個候選人
的信息,它包含2 個整數,先後是控方和辯方對該候選人的打分。候選人按出現的先後從1
開始編號。兩組有效數據之間以空行分隔。最後一組數據n=m=0
輸出要求
對每組數據,先輸出一行,表示答案所屬的組號, 如 'Jury #1', 'Jury #2', 等。接下來的
一行要象例子那樣輸出陪審團的控方總分和辯方總分。再下來一行要以升序輸出陪審團裏每
個成員的編號,兩個成員編號之間用空格分隔。每組輸出數據須以一個空行結束。
輸入樣例
4 2
1 2
2 3
4 1
6 2
0 0
輸出樣例
Jury #1
Best jury has value 6 for prosecution and value 4 for defence:
2 3

 

用動態規劃來解

動態規劃可以看成是重複子問題+遞歸

設p爲控方向量,d爲辯方向量

評分從-400到400
f(j,k)爲選取第j個人,評分差爲k的辯控總分
對於任意的i,i大於0小於n,則有
f(j,k)=f(j-1+1,x+p[i]-d[i])
則就有
f(j,k)=f(j-1,x)+p[i]+d[i];

如果新的f(j,k)大於舊的,則替換舊的,否則不替換

初始值爲k=0,在程序中或許是某個值,以免避免序號k出現負值。
那麼初始的f(0,0)=0;
在第一輪的時候只有辯控差爲0的合理
對所有的候選人做
f(1,p[i]-d[i])=max(f(1,p[i]-d[i]),f(0,0)+p[i]+d[i]);
這樣就可以完成選一個人的操作。
做完之後離k=0最近的非負的就是我們要的最大的辯控和。下標就是辯控差。
同理,如果選兩個的話,第二輪
k=-400~400
如果f(1,k)合理(此時,只有在第一輪中算出來的合理)
f(2,k+p[i]-d[i])=max(f(2,k+p[i]-d[i]),f(1,k)+p[i]+d[i]);

如果要保存搜索得到的路徑
設路徑path保存路徑向量
path(j,k)保存推薦第j個陪審員時候,辯控差爲k的候選人。
對應上面的f函數,初始值都設爲0。
如果只找一個候選人
則本身path中沒有任何的值,即沒有推薦任何的人。也就是說,推薦第一個人的時候,誰都可以(若推薦第二個人,則以前推薦過的不能再次推薦)
在推薦第一個候選人的時候,只管保存path[0][p[i]-d[i]]=i ;

當選取多個候選人的時候,在更新f(j,k)的同時更新path,因爲更新f(j,k)的同時,意味着選了新的候選人,所以需要更新路徑

 

更新路徑的時候要注意,已經在路徑中的不能重複,即已經選擇的陪審團成員不能重複選擇,所以要有個路徑回看的過程。


當以上都做完之後,
定義一個數組result來取路徑
對i:1~m
 result[i]=path[m-i+1][k];
 k=k-p[result[i]]+d[result[i]];
這樣就都解決了。

 

【博客整理】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章