01背包

我们对于这类选或者不选的模型应该先思考能否用01背包来解。

毫无疑问物体的价值可以看成最大的d+p值,那么体积呢?题目的另一个限制条件是d-p的和的绝对值最小,这启发我们把每个物体的d-p的值当作体积。

可以尝试设计状态f[i, j, k]表示从前i个物品中选j个,体积是k的最大价值。

同样的,我们可以用滚动数组的方法把第一维i去掉。

那么得到状态转移方程:

f[j, k] = max(f[j - 1, k - d[i] - p[i]] + d[i] + p[i], f[j, k])

对于j这一维,用倒序即可保证状态的更新.

但是这里的体积可能是负数,为了保证下标为正数,我们可以先整体右移下标的区间,最后从重心两边寻找最近点即可找到体积差最小的状态。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 305;
int a[N], b[N], dp[N][8005];
vector<int> p[N][8005];
int main(){ int n, m, _ = 0;
while(~scanf("%d%d", &n, &m) && n && m){
for(int i = 0; i <= N - 1; i ++)
for(int j = 0; j < 1000; j ++)
p[i][j].clear();
for(int i = 1; i <= n; i ++){
int x = read(), y = read();
a[i] = x - y, b[i] = x + y;
}
full(dp, 0xcf);
int now = 20 * m; dp[0][now] = 0;
for(int i = 1; i <= n; i ++){
for(int j = m; j >= 1; j --){
for(int k = 2 * now; k >= a[i]; k --){
if(dp[j][k] < dp[j - 1][k - a[i]] + b[i]){
dp[j][k] = dp[j - 1][k - a[i]] + b[i];
p[j][k] = p[j - 1][k - a[i]];
p[j][k].push_back(i);
}
}
}
}
int i = 0;
for(; dp[m][i + now] < 0 && dp[m][now - i] < 0; i ++);
int k = dp[m][i + now] > dp[m][now - i] ? i : -i;
int sumd = (dp[m][now + k] + k) / 2, sump = (dp[m][now + k] - k) / 2;
printf("Jury #%d \n", ++_);
printf("Best jury has value %d for prosecution and value %d for defence:\n", sumd, sump);
for(int j = 0; j < p[m][now + k].size(); j ++){
printf(" %d", p[m][now + k][j]);
}
printf("\n");
}
return 0;
}

POJ 1015 Jury Compromise (算竞进阶习题)的更多相关文章

  1. POJ 2449 Remmarguts' Date (算竞进阶习题)

    A* + dijkstra/spfa 第K短路的模板题,就是直接把最短路当成估价函数,保证估价函数的性质(从当前状态转移的估计值一定不大于实际值) 我们建反图从终点跑最短路,就能求出从各个点到终点的最 ...

  2. POJ 2245 Addition Chains(算竞进阶习题)

    迭代加深dfs 每次控制序列的长度,依次加深搜索 有几个剪枝: 优化搜索顺序,从大往下枚举i, j这样能够让序列中的数尽快逼近n 对于不同i,j和可能是相等的,在枚举的时候用过的数肯定不会再被填上所以 ...

  3. 背包系列练习及总结(hud 2602 && hdu 2844 Coins && hdu 2159 && poj 1170 Shopping Offers && hdu 3092 Least common multiple && poj 1015 Jury Compromise)

    作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢htt ...

  4. OpenJudge 2979 陪审团的人选 / Poj 1015 Jury Compromise

    1.链接地址: http://bailian.openjudge.cn/practice/2979 http://poj.org/problem?id=1015 2.题目: 总Time Limit: ...

  5. POJ 1015 Jury Compromise(双塔dp)

    Jury Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33737   Accepted: 9109 ...

  6. poj 1015 Jury Compromise(背包+方案输出)

    \(Jury Compromise\) \(solution:\) 这道题很有意思,它的状态设得很...奇怪.但是它的数据范围实在是太暴露了.虽然当时还是想了好久好久,出题人设了几个限制(首先要两个的 ...

  7. POJ 1821 Fence (算竞进阶习题)

    单调队列优化dp 我们把状态定位F[i][j]表示前i个工人涂了前j块木板的最大报酬(中间可以有不涂的木板). 第i个工人不涂的话有两种情况: 那么F[i - 1][j], F[i][j - 1]就成 ...

  8. POJ 3974 Palindrome (算竞进阶习题)

    hash + 二分答案 数据范围肯定不能暴力,所以考虑哈希. 把前缀和后缀都哈希过之后,扫描一边字符串,对每个字符串二分枚举回文串长度,注意要分奇数和偶数 #include <iostream& ...

  9. POJ 1966 Cable TV Network (算竞进阶习题)

    拆点+网络流 拆点建图应该是很常见的套路了..一张无向图不联通,那么肯定有两个点不联通,但是我们不知道这两个点是什么. 所以我们枚举所有点,并把每个点拆成入点和出点,每次把枚举的两个点的入点作为s和t ...

随机推荐

  1. Android SDK 开发——发布使用踩坑之路

    前言 在 Android 开发过程中,有些功能是通用的,或者是多个业务方都需要使用的. 为了统一功能逻辑及避免重复开发,因此将该功能开发成一个 SDK 是相当有必要的. 背景 刚好最近自己遇到了类似需 ...

  2. postgresql如何让主键自增

    法一: Sql代码 收藏代码 CREATE TABLE customers ( customerid SERIAL primary key , companyname character varyin ...

  3. SQLServer事务在C#当中的应用

    1:事务是什么 事务指的是一系列SQL操作的逻辑工作单元,,要么完全地执行,要么完全地不执行. 一个逻辑工作单元必须有4个属性,原子性(Atomic).一致性(Consistent).隔离型(Isol ...

  4. 使用C# 操作存储过程,执行sql语句通用类

    如何使用C# 操作存储过程,执行sql语句? 闲话不多说,直接上代码:     /// <summary>    /// Sql通用类    /// </summary>    ...

  5. Java基础差,需要怎么补

    本文首发于本博客 猫叔的博客,转载请申明出处 感谢sugar的提问:Java基础差,需要怎么补? 欢迎关注公众号:Java猫说 我整体的总结了一下,大致分为以下的几个点说一下: 1.善于使用搜索引擎 ...

  6. [Java] 为什么字符串比较不能用两个等号(==)

    Java中,使用"=="比较字符串时,判断的是两个字符串是否存放在相同的位置.如果两个字符串存放在相同的位置,那么它们就是相同的,使用"=="比较的结果也就是T ...

  7. Android为TV端助力:自定义view之太阳

    先看效果图 package com.hhzt.iptv.lvb_w8.view; import android.content.Context;import android.graphics.Canv ...

  8. 读书笔记之_Win10 与Jmeter5.1.1界面兼容:

    读书笔记之win10 与jmeter5.1.1界面兼容:   调整前:

  9. 为什么CynosDB叫真正的云原生数据库?

    本文由腾讯云数据库发表 注:本文摘自2018年11月22日腾讯云数据库CynosDB新品发布会的演讲实录.随着互联网信息的发展,大家也对云这个词汇也不是特别陌生了,作为全球首选的云服务厂商之一的腾讯云 ...

  10. Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax(思维题)

    Problem   Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax Time Limit: 2000 mSec Problem ...