第一次做dp分组的问题,百度的~~

http://poj.org/problem?id=1015

题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团。选m人的办法是:控方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可。

2 2

1 2

3 4

大概思路如下。

设dp[i][j]表示选i个人,当前的差值是j的时候,最大的和值是dp[i][j]

由于他是abs的,这样会产生相同的j。但是应该分开的,因为路径是不同的,产生的dp[i][j]那个值不应该被其他覆盖。

然后就是记录路径,

path[i][j]表示是由那个值进化而来的,即可说是上一个,也可以说是这个的值。

然后思路就是,

枚举i : 1 to m //选m个人

  k : 0 to 2 * fix //枚举差值。

    判断即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int fix = 400;
int dp[30][1000]; // dp[i][j]表示选了i个人,差值为j的时候,的最大和值
int path[30][1000];
int D[200 + 20];
int P[200 + 20];
int sum[200 + 20];
int dis[200 + 20];
set<int>ans;
int n, m;
void init() {memset(dp, -1, sizeof dp);memset(path, -1, sizeof path);ans.clear();
}
void work() {init();for (int i = 1; i <= n; ++i) {cin >> D[i] >> P[i];dis[i] = D[i] - P[i];sum[i] = D[i] + P[i];}dp[0][fix] = 0; //因为fix了,所以0的时候,其实就是fix的时候for (int i = 1; i <= m; ++i) {for (int k = 0; k <= 2 * fix; ++k) {if (dp[i - 1][k] >= 0) { //如果这个状态可行,才能再选举一个人进来for (int j = 1; j <= n; ++j) {if (dp[i - 1][k] + sum[j] > dp[i][k + dis[j]]) { //加了这个人后,最优解变大,然后差值就是变成k + dis[j]的//还需要检查j是否在dp[i - 1][k]这个路径上了。int t = path[i - 1][k];int pre = i - 1;int ff = k;bool flag = true;while (t != -1) {if (t == j) {flag = false;break;}ff -= dis[t]; //减去当前这个点的值t = path[--pre][ff];}if (flag == true) {dp[i][k + dis[j]] = dp[i - 1][k] + sum[j];path[i][k + dis[j]] = j;}}}}}}int i = fix;int j = 0;while (dp[m][i + j] < 0 && dp[m][i - j] < 0) { //排除没用的状态++j;}int KK; //最小的差值 对应的那个dp,可以对应输出最大的和值if (dp[m][i + j] > dp[m][i - j]) {KK = i + j;} else KK = i - j;int t = path[m][KK];int pre = m;int ff = KK;while (t != -1) {ans.insert(t);ff -= dis[t];t = path[--pre][ff];}int df = 0, pf = 0;for (set<int> :: iterator it = ans.begin(); it != ans.end(); ++it) {df += D[*it];pf += P[*it];}static int gg = 0;printf("Jury #%d\n", ++gg);printf("Best jury has value %d for prosecution and value %d for defence:\n", df, pf);for (set<int> :: iterator it = ans.begin(); it != ans.end(); ++it) {cout << " " << *it;}cout << endl << endl;
}int main() {
#ifdef localfreopen("data.txt","r",stdin);
#endifIOS;while (cin >> n >> m && (n + m)) {work();}return 0;
}

View Code

转载于:https://www.cnblogs.com/liuweimingcprogram/p/6027041.html

POJ 1015 Jury Compromise dp分组相关推荐

  1. POJ1015陪审团(Jury Compromise)——dp+路径记录

    题目:http://poj.org/problem?id=1015 差值是有后效性的,所以"转化为可行性",开一维记录"能否达到这个差值". 当然可以开两维分别 ...

  2. poj 1015 Jury Compromise_dp

    题意:n个陪审团,每个陪审团有x,y值,选出m个陪审团,要求 (sum(xi)-sum(yi))最少,当 (sum(xi)-sum(yi))最少有多个,取sum(xi)+sum(yi)最大那个 ,并顺 ...

  3. Jury Compromise POJ - 1015

    Jury Compromise POJ - 1015 题意: 在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中 ...

  4. ZOJ 3450 Doraemon's Railgun (DP·分组背包)

    题意  多啦A梦有一个超电磁炮  然后要打死n堆敌人  在同一条射线上的敌人只有先打死前面的一堆才能打后面的一堆  给你打死某堆敌人需要的时间和这堆敌人的人数   问你在T0时间内最多打死多少个敌人 ...

  5. poj 1015(dp)

    看的解题报告..http://blog.csdn.net/lyy289065406/article/details/6671105 View Code 1 #include <iostream& ...

  6. poj 1185(状压dp)

    题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...

  7. poj1015 Jury Compromise

    dp题,类似于01背包的转移 需要注意的是:背包容量在有的时候可能为负数,所以需要算出最大数据量整体平移 像01背包一样直接倒序循环j并不能保证每一个物品只选一个,两个等价的物品在计算时可能会重复使用 ...

  8. poj 2948 Martian Mining (dp)

    http://poj.org/problem?id=2948 意:一个row*col的矩阵,每个格子内有两种矿yeyenum和bloggium,并且知道它们在每个格子内的数量是多少.如图所示,最北边有 ...

  9. [POJ 1742] Coins 【DP】

    题目链接:POJ - 1742 题目大意 现有 n 种不同的硬币,每种的面值为 Vi ,数量为 Ni ,问使用这些硬币共能凑出 [1,m] 范围内的多少种面值. 题目分析 使用一种 O(nm) 的 D ...

最新文章

  1. CXF做的webservice简单例子
  2. 压力测试工具ab 及 centos下单独安装方法
  3. 三、数据分析前,打下数据处理基础(下)
  4. EntityFramework Core 3.x上下文构造函数可以注入实例呢?
  5. 第三四五章(PTA复习)
  6. 随笔 - 142 文章 - 0 评论 - 2294 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 权限管理...
  7. eNSP 华为帧中继实验
  8. java List转换为字符串并加入分隔符的一些方法总结
  9. 用CMake编译lua
  10. wpf Content数据绑定StringFormat起作用的原理和解决(转)
  11. Java中的网络编程
  12. 天呐,你竟然在配置文件配明文密码?
  13. pycharm隐藏窗口
  14. 8. Celery 4.3.0 Periodic Tasks 周期性任务调度
  15. 什么是IBinder
  16. python学习笔记:第8天 文件操作
  17. 我“听”得见你爱的心跳
  18. Delphi官方文档
  19. 怎么给win10电脑设置每个月16号定时提醒
  20. 标数据,您的招投标业务专家

热门文章

  1. 2014校招 百度试题及答案
  2. 使用HttpUnit进行集成测试
  3. MTK A/B system说明及配置
  4. 2018推荐的android手机,外媒推荐:2018年下半年最值得期待的5款安卓手机
  5. 网络协议:TCP连接管理
  6. 操作系统之进程和线程
  7. (3)QuartusII 封装网表文件(FPGA不积跬步101)
  8. (22)FPGA面试技能提升篇(MicroBlaze、PowerPC)
  9. 给单文档框架添加背景图
  10. php判断值是否为空然后定义,判断php变量是不是定义,是否为空