生活随笔
收集整理的這篇文章主要介紹了
280. 陪审团 poj1015(背包DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在一個遙遠的國家,一名嫌疑犯是否有罪需要由陪審團來決定。
陪審團是由法官從公民中挑選的。
法官先隨機挑選N個人(編號1,2…,N)作為陪審團的候選人,然后再從這N個人中按照下列方法選出M人組成陪審團。
首先,參與訴訟的控方和辯方會給所有候選人打分,分值在0到20之間。
第 i 個人的得分分別記為p[i]和d[i]。
為了公平起見,法官選出的M個人必須滿足:辯方總分D和控方總分P的差的絕對值|D-P|最小。
如果選擇方法不唯一,那么再從中選擇辨控雙方總分之和D+P最大的方案。
求最終的陪審團獲得的辯方總分D、控方總分P,以及陪審團人選的編號。
輸入格式
輸入包含多組測試數據。
每組測試數據第一行包含兩個整數N和M。
接下來N行,每行包含兩個整數p[i]和d[i]。
每組測試數據之間隔一個空行。
當輸入數據N=0,M=0時,表示結束輸入,該數據無需處理。
輸出格式
對于每組數據,第一行輸出’Jury #C’,C為數據編號,從1開始。
第二行輸出“Best jury has value P for prosecution and value D for defence:”,P為控方總分,D為辯方總分。
第三行輸出按升序排列的陪審人選編號,每個編號前輸出一個空格。
每組數據輸出完后,輸出一個空行。
數據范圍
1≤N≤200,
1≤M≤20
輸入樣例:
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
思路: dp(i,j)代表選了前i個數的時候,(p[i] - d[i])和為j的最大(p[i] + d[i])和。
再開一個路徑數組path(x,i,j)記錄到了第x個數,選了前i個數,(p[i] - d[i])和為j的時候,對應的編號。
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std
;#define INF 0x3f3f3f3fconst int maxn
= 205;
vector
<int>ans
;
int p
[maxn
],d
[maxn
];
int path
[maxn
][25][805],dp
[25][805],suma
,sumb
;void dfs(int i
,int j
,int k
)
{if(j
== 0)return;int last
= path
[i
][j
][k
];dfs(last
- 1,j
- 1,k
- (p
[last
] - d
[last
]));ans
.push_back(last
);suma
+= p
[last
];sumb
+= d
[last
];
}int main()
{int n
,m
;int kase
= 0;while(~scanf("%d%d",&n
,&m
) && n
&& m
){for(int i
= 1;i
<= n
;i
++){scanf("%d %d",&p
[i
],&d
[i
]);}ans
.clear();suma
= 0;sumb
= 0;memset(dp
,-INF
,sizeof(dp
));dp
[0][400] = 0;for(int i
= 1;i
<= n
;i
++){for(int j
= 0;j
<= m
;j
++)for(int k
= 0;k
<= 800;k
++)path
[i
][j
][k
] = path
[i
- 1][j
][k
];for(int j
= m
;j
> 0;j
--)for(int k
= 0;k
<= 800;k
++){if(k
- (p
[i
] - d
[i
]) < 0 || k
- (p
[i
] - d
[i
]) > 800)continue;if(dp
[j
][k
] < dp
[j
- 1][k
- (p
[i
] - d
[i
])] + (p
[i
] + d
[i
])){dp
[j
][k
] = dp
[j
- 1][k
- (p
[i
] - d
[i
])] + (p
[i
] + d
[i
]);path
[i
][j
][k
] = i
;}}}int res
= 0;for(int i
= 0;i
<= 400;i
++){if(dp
[m
][400 + i
] >= 0 && dp
[m
][400 + i
] >= dp
[m
][400 - i
]){res
= 400 + i
;break;}if(dp
[m
][400 - i
] >= 0 && dp
[m
][400 - i
] >= dp
[m
][400 + i
]){res
= 400 - i
;break;}}dfs(n
,m
,res
);printf("Jury #%d\nBest jury has value %d for prosecution and value %d for defence:\n",++kase
,suma
,sumb
);for(int i
= 0;i
< ans
.size();i
++){printf(" %d",ans
[i
]);}printf("\n\n");}return 0;
}
總結
以上是生活随笔為你收集整理的280. 陪审团 poj1015(背包DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。