PKU ACM 1015 Jury Compromise (DP)
2011-09-26 22:05
295 查看
题目链接:Jury Compromise
问题描述:
控辩双方选择陪审团成员。每个陪审团成员对控辩双方来说,都有一个数值表示合适程度(0 ~ 20)。现在要从n个待选陪审员中选出m位,要是这m个人对控辩双方合适程度的差最小。如果有差相同的情况,那么选择对控辩双方合适程度的和较大的那个组合。
主要思路:
1. 动态规划
2. 记录从 n 个人中选出 j 个,并且当前组合的控辩双方合适程度差为 k,且控辩双方合适程度和为 w,记录形式为:
f[j][k] = w
3. 如果已知 f[j][k] = w,并且有一个陪审员 i 尚未被选中
那么就有 f[j+1][k+minus[i]] = w + plus[i]
这里
minus[i] 和 plus[i] 表示第 i 个陪审员的控辩合适程度差和合适程度和。
4. 下面就是对路径的记录,这里用 path[j][k] = i记录 i j k 之间的连接关系。
个人体会:
感觉动态规划的方法,其实并不神秘。只不过是在暴力破解的过程中,记录下中间步骤的解,避免重复的计算。
源代码:
问题描述:
控辩双方选择陪审团成员。每个陪审团成员对控辩双方来说,都有一个数值表示合适程度(0 ~ 20)。现在要从n个待选陪审员中选出m位,要是这m个人对控辩双方合适程度的差最小。如果有差相同的情况,那么选择对控辩双方合适程度的和较大的那个组合。
主要思路:
1. 动态规划
2. 记录从 n 个人中选出 j 个,并且当前组合的控辩双方合适程度差为 k,且控辩双方合适程度和为 w,记录形式为:
f[j][k] = w
3. 如果已知 f[j][k] = w,并且有一个陪审员 i 尚未被选中
那么就有 f[j+1][k+minus[i]] = w + plus[i]
这里
minus[i] 和 plus[i] 表示第 i 个陪审员的控辩合适程度差和合适程度和。
4. 下面就是对路径的记录,这里用 path[j][k] = i记录 i j k 之间的连接关系。
个人体会:
感觉动态规划的方法,其实并不神秘。只不过是在暴力破解的过程中,记录下中间步骤的解,避免重复的计算。
源代码:
#include <iostream> #include <algorithm> using namespace std; int n, m; int* minus; int* plus; int f[20+1][800+1]; int path[20+1][800+1]; bool available(int di, int dj, int dk) { while(dj) { if(path[dj][dk] == di) { return false; } else { dk = dk - minus[path[dj][dk]]; dj = dj - 1; } } return true; } void DP() { memset(f, -1, sizeof(f)); memset(path, 0, sizeof(path)); f[0][0] = 0; for(int j = 0; j < m; j++) { for(int k = 0; k < 40 * m; k++) { if(f[j][k] != -1) { for(int i = 0; i < n; i++) { if(available(i, j, k)) //判断第 i 个陪审员是否已被选中 { if(f[j+1][k+minus[i]] < f[j][k] + plus[i]) { f[j+1][k+minus[i]] = f[j][k] + plus[i]; path[j+1][k+minus[i]] = i; } } } } } } } void Print() { int k = 20 * m; int result = -1; int step = 1; if(f[m][k] != -1) { result = k; } else { while(true) { if((f[m][k+step] != -1) || (f[m][k-step] != -1)) { result = f[m][k+step] > f[m][k-step] ? (k+step) : (k-step); break; } step = step + 1; } } int j = m; int i = 0; k = result; int* resultpath = new int[m]; while(j) { resultpath[i] = path[j][k]; k = k - minus[path[j][k]]; j = j - 1; i = i + 1; } int prosecution = 0, defence = 0; for(i = 0; i < m; i++) { prosecution += minus[resultpath[i]] - 20 + plus[resultpath[i]]; defence += plus[resultpath[i]] - minus[resultpath[i]] + 20; } cout << "Best jury has value " << prosecution / 2 << " for prosecution and value " << defence / 2 << " for defence: " << endl; sort(resultpath, resultpath + m); for(i = 0; i < m; i++) { cout << resultpath[i] + 1 << " "; } cout << endl; } int main() { int index = 0; int a, b; while(true) { cin >> n >> m; if(n == 0) break; index++; minus = new int ; plus = new int ; for(int i = 0; i < n; i++) { cin >> a >> b; minus[i] = a - b + 20; plus[i] = a + b; } DP(); cout << "Jury #" << index << endl; Print(); } return 0; }
相关文章推荐
- POJ1015-Jury Compromise 以及 uva 323正确二维DP解法
- poj 1015 Jury Compromise_dp
- 【dp】POJ 1015 Jury Compromise
- poj 1015 Jury Compromise_dp
- pku 1015 Jury Compromise DP
- POJ 1015 Jury Compromise(双塔DP)
- poj 1015 Jury Compromise(DP)
- POJ 1015 Jury Compromise【DP】
- POJ 1015 Jury Compromise(DP)
- POJ 1015 Jury Compromise(双塔DP)
- DP-POJ-1015-Jury Compromise
- POJ 1015 Jury Compromise【DP】
- POJ 1015 Jury Compromise ---- DP
- [dp] poj 1015 Jury Compromise
- POJ1015-Jury Compromise-dp
- POJ 1015 Jury Compromise(DP)
- poj 1015 Jury Compromise 状态压缩DP(不压缩也行)
- POJ1015 Jury Compromise(DP)
- pku1015 Jury Compromise
- (POJ 1015) Jury Compromise 经典dp问题 (n选m)