日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

<<算法竞赛进阶指南>>:陪审团

發布時間:2023/12/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 <<算法竞赛进阶指南>>:陪审团 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在一個遙遠的國家,一名嫌疑犯是否有罪需要由陪審團來決定。
陪審團是由法官從公民中挑選的。

法官先隨機挑選 NNN 個人(編號 1,2…,N1,2…,N1,2,N)作為陪審團的候選人,然后再從這 NNN 個人中按照下列方法選出 MMM 人組成陪審團。

首先,參與訴訟的控方和辯方會給所有候選人打分,分值在 000202020 之間。
iii 個人的得分分別記為 p[i]p[i]p[i]d[i]d[i]d[i]。 為了公平起見,法官選出的 MMM 個人必須滿足:辯方總分 DDD 和控方總分 PPP 的差的絕對值 ∣D?P∣|D?P|D?P 最小。
如果選擇方法不唯一,那么再從中選擇辨控雙方總分之和 D+PD+PD+P 最大的方案。求最終的陪審團獲得的辯方總分 DDD、控方總分 PPP,以及陪審團人選的編號。

注意:若陪審團的人選方案不唯一,則任意輸出一組合法方案即可。

輸入格式:

輸入包含多組測試數據。
每組測試數據第一行包含兩個整數 NNNMMM
接下來 NNN 行,每行包含兩個整數 p[i]p[i]p[i]d[i]d[i]d[i]
每組測試數據之間隔一個空行。
當輸入數據 N=0,M=0N=0,M=0N=0M=0 時,表示結束輸入,該數據無需處理。

輸出格式:
對于每組數據,第一行輸出 KaTeX parse error: Expected 'EOF', got '#' at position 6: Jury #?CCCC
為數據編號,從 111 開始。
第二行輸出 BestjuryhasvaluePforprosecutionandvalueDfordefence:Best jury has value P for prosecution and value D for defence:BestjuryhasvaluePforprosecutionandvalueDfordefence:PPP為控方總分,DDD 為辯方總分。
第三行輸出按升序排列的陪審人選編號,每個編號前輸出一個空格。
每組數據輸出完后,輸出一個空行。

數據范圍:
1≤N≤2001≤N≤2001N200
1≤M≤201≤M≤201M20
0≤p[i],d[i]≤200≤p[i],d[i]≤200p[i],d[i]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

首先 遇到背包問題, 確定背包類型, 每個人只能選一個, 故為 010101 背包, 然后題目要求具體方案, 首先答案要求滿足兩個條件, 第一是要 ∣D?P∣|D - P|D?P 最小,其次是 D+PD + PD+P 最大, 我們可以將 D+PD + PD+P 定義為背包的屬性

狀態定義: f[i][j][k]f[i][j][k]f[i][j][k]: 在前 iii 個人中選, 總人數不超過 jjj, 并且總差值為 kkk 的集合
狀態屬性: D+PD + PD+P 的最大值
狀態計算: 選第 iii 個人 不選第 iii 個人
f[i][j][k]=max(f[i?1][j][k],f[i?1][j?1][k?(p[i]?d[i])]+p[i]+d[i]);f[i][j][k] = max(f[i - 1][j][k], f[i - 1][j - 1][k - (p[i] - d[i])] + p[i] + d[i]);f[i][j][k]=max(f[i?1][j][k],f[i?1][j?1][k?(p[i]?d[i])]+p[i]+d[i]);

求出 D+PD + PD+P 的最大值并不難, 難點在于如何得到具體方案,我們可以通過方向搜一遍, 如果從終點狀態,一直迭代到起始狀態,能夠進行狀態轉移,我們就記下這個方案

注意: 由于p[i] 是從 111 ~ 202020, 所以 p[i]?d[i]p[i] - d[i]p[i]?d[i] 是從 ?40-40?40 ~ 404040, 所以總的 p[i]?d[i]p[i] - d[i]p[i]?d[i] 是從 ?400-400?400 ~ 400400400, 但是如果直接使用,會導致數組越界,所以我們加上一個偏移量取名為 basebasebase,其值 400400400, 故差值的范圍就會變成 000 ~ 800800800

#include<bits/stdc++.h>using namespace std;const int N = 210, M = 810, base = 400;int f[N][21][M], p[N], d[N], ans[N], n, m;int main() {int T = 1;while(cin >> n >> m, n, m){for(int i = 1; i <= n; i ++ ) cin >> p[i] >> d[i]; //讀入memset(f, -0x3f, sizeof f); //因為求最大值, 故賦值為負無窮f[0][0][base] = 0; //初始化為0int cnt = 0; //初始化for(int i = 1; i <= n; i ++) //枚舉前i個人for(int j = 0; j <= m; j ++) //枚舉已經選了的人for(int k = 0; k < M; k ++ ) //枚舉差值 0~801{f[i][j][k] = f[i - 1][j][k]; //不選第 i 個人int t = k - (p[i] - d[i]); //計算出差值,看是否符合題意if(t < 0 || t > M ) continue; if(j < 1) continue; //是否可以轉移f[i][j][k] = max(f[i][j][k], f[i - 1][j - 1][t] + p[i] + d[i]); //狀態轉移}int v = 0;while( f[n][m][base + v] < 0 && f[n][m][base - v] < 0) v ++;// 當v小于0和v大于0 都不合題意是, v++;if(f[n][m][base + v] > f[n][m][base - v]) v = base + v;else v = base - v;//當v,-v都存在時,取最大值int j = m, i = n, k = v;while(j){if(f[i][j][k] == f[i - 1][j][k]) i --;//如果可以不選第i個人else {ans[cnt ++ ] = i; //選了第i個人k -= p[i] - d[i]; //差值減小i --, j --; //減小}}int a = 0, b = 0;for(int i = 0; i < cnt; i ++ ) a += p[ans[i]], b += d[ans[i]];//記錄答案printf("Jury #%d\n", T++);printf("Best jury has value %d for prosecution and value %d for defence:\n", a, b);sort(ans, ans + cnt); //排序,保證編號是從小到大的//打印方案for(int i = 0; i < cnt; i ++ ) cout << ans[i] << ' ';cout << '\n';cout << '\n';} }

總結

以上是生活随笔為你收集整理的<<算法竞赛进阶指南>>:陪审团的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。