码迷,mamicode.com
首页 > 其他好文 > 详细

POJ1015 动态规划

时间:2014-07-24 22:05:22      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   re   

POJ1015

问题重述:

在n个候选者中选取m个人进入陪审团。每个候选者获得两项评分:D[j],P[j]。求解最佳评审团,使得在每个成员的两项评分和之差 最小的情况下,使得两项评分和之和 最大。

分析:

欲采用动态规划求解,必须先找到最优子结构。假如考虑评分差的绝对值,它的子问题并不一定是最优解。若考虑一定评分差下的评分和最大值,则拥有最优子结构。

用dp[i][j]表示在第i个评委评分后,评分差是j的最大评分和,得到递归公式:

dp[i][j] = max{ dp[ i - 1 ][ j - (D[i] - P[j]) ] + D[i] + P[j], dp[ i - 1 ][j] }

AC代码 

 1 //Memory: 380K        Time: 79MS
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 int dp[21][810];
10 int prior[21][810];
11 int n, m;
12 int q[201], d[201];
13 const int offset = 405;
14 int r[21];
15 
16 bool findPath(int n, int s, int target)
17 {
18     if (n == 0) return false;
19     if (target == prior[n][s + offset]) return true;
20     int p = prior[n][s + offset];
21     return findPath(n - 1, s - (d[p] - q[p]), target);
22 }
23 
24 void output(int ans)
25 {
26     for (int j = m ; j >= 1; j--) {
27         r[j - 1] = prior[j][ans + offset];
28         int p = prior[j][ans + offset];
29         ans -= (d[p] - q[p]);
30     }
31     sort(r, r + m);
32     for (int i = 0; i < m; i++)
33         cout << " " << r[i];
34     cout << endl << endl;
35 }
36 
37 int main()
38 {
39     int cas = 1; 
40     while ( cin >> n >> m && n ) {
41         for (int i = 1; i <= n; i++)
42             cin >> d[i] >> q[i];
43         memset(dp, -1, sizeof(dp));
44         memset(prior, 0, sizeof(prior));
45         dp[0][offset] = 0;
46 
47         for (int i = 1; i <= m; i++) {
48             for (int j = 1; j <= n; j++) {
49                 int ss = d[j] + q[j];
50                 int dd = d[j] - q[j];
51                 for (int s = -400; s <= 400; s++) {
52                     if (s - dd < -400 || s - dd > 400) continue;
53                     if (dp[i - 1][s - dd + offset] != -1 && dp[i - 1][s - dd + offset] + ss > dp[i][s + offset] && !findPath(i - 1, s - dd, j)) {
54                         dp[i][s + offset] = dp[i - 1][s - dd + offset] + ss;
55                         prior[i][s + offset] = j;
56                     }
57                 }
58             }
59         }
60         for (int i = 0; i <= 400; i++) {
61             if (dp[m][offset + i] == -1 && dp[m][offset - i] == -1) continue;
62 
63             int ans = dp[m][offset + i] > dp[m][offset - i] ? i : -i;
64 
65             int sd = (dp[m][ans + offset] + ans) / 2;
66             int sq = (dp[m][ans + offset] - ans) / 2;
67 
68             cout << "Jury #" << cas++ << endl;
69             cout << "Best jury has value " << sd << " for prosecution and value "
70                 << sq << " for defence:" << endl;
71             output(ans);
72             break;
73         }
74     }
75     return 0;
76 }

POJ1015 动态规划,布布扣,bubuko.com

POJ1015 动态规划

标签:style   blog   http   color   os   io   for   re   

原文地址:http://www.cnblogs.com/junxie/p/3866100.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!