POJ 1015 陪審團人選 動態規劃

2021-09-30 04:40:25 字數 1162 閱讀 4827

用f[i][j]表示,取i個候選人,使其辯控差為j 的所有方案中,辯控和最大的那個方案的控辯和。

要求f[i][j] 顯然要從乙個可行的方案 f[i-1][x] 演化而來。可行方案f(i-1, x)能演化成方案f(j, k)的必要條件是:

存在某個候選人k,k 在方案f(i-1, x)中沒有被選上,且x+v(k) = j;(v(k)為第k個人的控辯差);

選出 f(i-1, x) + s(k)(控辯和)  的值最大的那個,那麼方案f(i-1, x)再加上候選人k,就演變成了方案 f(i, j)。

這中間需要將乙個方案都選了哪些人都記錄下來。不妨將方案f(i, j)中最後選的那個候選人的編號,記在二維

陣列的元素path[i][j]中。那麼方案f(i, j)的倒數第二個人選的編號,就是path[i-1][j-v[path[i][j]]。

假定最後算出了解方案的辯控差是k,那麼從path[m][k]出發,就能順藤摸瓜一步步求出所有被選中的候選人。

#include #include #include #include int compare(void const* a, void const* b)

int main()

q[0][0] = 400;

qnum[0] = 1;

f[0][400] = 0;

for (i=0; if[i+1][q[i][j]+p[k]-d[k]])

if (t1==0) //沒有被選上,可選

f[i+1][q[i][j]+p[k]-d[k]] = f[i][q[i][j]]+p[k]+d[k];

path[i+1][q[i][j]+p[k]-d[k]] = k;}}

}}

}min = 900; //計算控方和辯方差值的絕對值最小值

for (i=0; if[m][400-min]) min = min+400; //選最小差值中總分和最大的

else min = 400-min;

printf("jury #%d\n", casenum++);

printf("best jury has value %d for prosecution and value %d for defence:\n",

(min-400+f[m][min])/2, (400-min+f[m][min])/2);

for (i=0; i

poj1015陪審團 DP 路徑記錄

題目 dp的第一維是選了幾個人,第二維是當前d與p的差值,而值存的是當前d與p的和 技巧1 通過平移避免負角標,即 中的fix 技巧2 做完dp後找出最小的差的絕對值時,如下的那一小段 很有效率 技巧3 記錄路徑 更新路徑時每次判斷是否重複選了乙個人,重複則不更新 if f j k p i d i ...

poj 1015 動態規劃 難

這道題我是看別人的思路寫的,因為有個絕對值,無法轉移狀態,自己傻得非要把絕對值表示出來,其實可以在計算完成後篩選,我這個菜鳥估計是受揹包的的影響,想狀態的時候還想著前幾個中選出多少個。這道題的狀態是f i j i選了的人數,邊界為零,目標為m,j為d p a 的差值和,f值為d p b 值。記如何狀...

經典動態規劃題目 POJ 1015

在文章開始時,先宣告一下,小弟剛開始接觸acm,水平有限,所以這裡給出的程式是閹割版的,只實現了關鍵功能,無法ac 這道題類似於經典的陣列分割問題,可參見 程式設計之美 2.18 include include const int max n 202 const int max m 22 const...