POJ 1015 陪审团人选 [动态规划]
来源:互联网 发布:成都和重庆公务员知乎 编辑:程序博客网 时间:2024/05/21 17:16
动态规划太深奥了,太难规了,这题又是看《程序设计引导及在线实践》上面的思路和代码做的,具体规划思路如下:
用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 <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>int compare(void const* a, void const* b){ return *(int*)a - *(int*)b;}int main(){ int n, m, i, j, k, t1, t2, casenum=1, min; int f[21][1000], p[201], d[201], path[21][1000]; int Qnum[21], Q[21][900]; //队列 int ans[21]; while (scanf("%d %d", &n, &m) && n) { memset(f, -1, sizeof(f)); //这样也行!!赋值之后是-1;为什么呢??? memset(Qnum, 0, sizeof(Qnum)); for (i=1; i<=n; i++) { scanf("%d %d", &p[i], &d[i]); } Q[0][0] = 400; Qnum[0] = 1; f[0][400] = 0; for (i=0; i<m; i++) { for (j=0; j<Qnum[i]; j++) { for (k=1; k<=n; k++) { if(f[i][Q[i][j]]+p[k]+d[k] > f[i+1][Q[i][j]+p[k]-d[k]]) { t1 = i; //以下检验k是否已经在f[i][Q[i][j]]中被选上 t2 = Q[i][j]; while (t1>0 && path[t1][t2]!=k) { t2 -= p[path[t1][t2]]-d[path[t1][t2]]; t1--; } if (t1==0) //没有被选上,可选 { if (f[i+1][Q[i][j]+p[k]-d[k]] == -1) { //添加到队列 Q[i+1][Qnum[i+1]] = Q[i][j]+p[k]-d[k]; Qnum[i+1]++; } 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; i<Qnum[m]; i++) { if (abs(Q[m][i]-400) < min) min = abs(Q[m][i]-400); } if (f[m][400+min] > f[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<m; i++) //从后往前依次找被选中的m个人 { ans[i] = path[m-i][min]; min -= p[ans[i]]-d[ans[i]]; } qsort(ans, m, sizeof(int), compare); for (i=0; i<m; i++) printf(" %d", ans[i]); printf("\n\n"); }}
- POJ 1015 陪审团人选 [动态规划]
- poj-2979-陪审团的人选-C语言-动态规划
- POJ 1015 公正陪审团问题 动态规划
- Jury Compromise(陪审团的人选、动态规划题)
- OpenJudge 2979 陪审团的人选 / Poj 1015 Jury Compromise
- poj 1015 陪审团问题
- poj 1015 陪审团
- poj 1015 dp(陪审团成员的选择)
- [poj]动态规划1015
- NOI题库1980 陪审团的人选(POJ1015)
- poj 1015 动态规划 难
- 每日一题(5)——公正陪审团问题(动态规划)
- poj 1015 Jury Compromise 动态规划
- POJ 1015-Jury Compromise动态规划
- 经典动态规划题目(POJ 1015)
- poj 1015 Jury Compromise 动态规划
- poj 2411 动态规划
- Poj 1157(动态规划)
- ASP.NET 中TextBox设置ReadOnly或者Disable后获取不到值的解决办法
- 无论你的收入多少,请记得分成五份
- 读书笔记之编程之美 - 2.15 子数组之和的最大值(二维)
- start C++
- matlab图像处理基本函数
- POJ 1015 陪审团人选 [动态规划]
- 游戏
- 编写跨平台的文件操作类
- 获取控制台程序的HWND和HINSTANCE
- 内聚性
- 明年 此时 期待
- GNU flex unistd.h在VC下的编译问题
- 注册表右键单击出现项-与注册表对应关系
- javascript 取得当前用户的组和权限(上)