Description

【题目描述】

蛤布斯有n个物品和一个大小为m的背包,每个物品有大小和价值,它希望你帮它求出背包里最多能放下多少价值的物品。

【输入数据】

第一行两个整数n,m。接下来n行每行两个整数xi,wi,表示第i个物品的大小和价值。

【输出数据】

一行一个整数表示最大价值。

【样例输入】

5 100

95 80

4 18

3 11

99 100

2 10

【样例输出】

101

【数据范围】

对于20%的数据,xi<=1500。

对于另外30%的数据,wi<=1500。

对于100%的数据,n<=40,0<=m<=10^18,0<=xi,wi<=10^15。


中途相遇法这个东西比较有意思.

这题接近于可行的办法就是暴搜, O(2 ^ n), 但是会炸掉.

不难发现, 假如时间复杂度优化至O(2 ^ (n / 2)), 那么这题就是可以过的, 因此可以这样做:

把所有物品分为左右两半, 2 ^ (n / 2)枚举在同一半中每一种选取物品方案(即从小到大枚举i)所得到的价值以及, 记录入L[i], R[i]中(通过i的二进制拆分来得到当前的具体方案).

将L, R排序, 去掉那些空间大而价值小的方案, 扫一遍利用决策单调性即可得到答案.

附上代码(跑得好慢…)

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxN = 40;
struct item
{
long long size, val;
item(){}
item(long long first, long long second): size(first), val(second){}
}a[maxN], L[1 << (maxN >> 1)], R[1 << (maxN >> 1)];
int operator <(item x, item y)
{
if(x.size == y.size)
return x.val > y.val;
return x.size < y.size;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("pack.in", "r", stdin);
freopen("pack.out", "w", stdout);
#endif
ios::sync_with_stdio(false);
long long n, m;
cin >> n >> m;
for(int i = 0; i < n; i ++)
cin >> a[i].size >> a[i].val;
int mid = n >> 1;
for(int i = 0; i < 1 << (mid); i ++)
{
long long sizeSum = 0, valSum = 0;
for(int j = 0; j < mid; j ++)
if((i >> j) & 1)
sizeSum += a[j].size, valSum += a[j].val;
L[i] = item(sizeSum, valSum);
}
sort(L, L + (1 << mid));
long long cntL = 1;
for(int i = 1; i < 1 << mid; i ++)
if(L[cntL - 1].val < L[i].val)
L[cntL ++] = L[i];
for(int i = 0; i < 1 << (n - mid); i ++)
{
long long sizeSum = 0, valSum = 0;
for(int j = 0; j < n - mid; j ++)
if((i >> j) & 1)
sizeSum += a[mid + j].size, valSum += a[mid + j].val;
R[i] = item(sizeSum, valSum);
}
sort(R, R + (1 << (n - mid)));
long long cntR = 1;
for(int i = 1; i < 1 << (n - mid); i ++)
if(R[cntR - 1].val < R[i].val)
R[cntR ++] = R[i];
long long p = 0, q = cntR - 1;
long long ans = 0;
for(int p = 0; p < cntL; p ++)
{
while(L[p].size + R[q].size > m && q)
q --;
if(L[p].size + R[q].size > m)
continue;
ans = max(ans, L[p].val + R[q].val);
}
cout << ans;
}

中途相遇法 解决 超大背包问题 pack的更多相关文章

  1. 【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)

    题意:给定4个N元素几个A,B,C,D,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问有多少种选法.(N≤4000,D≤2^28) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...

  2. uva 6757 Cup of Cowards(中途相遇法,貌似)

    uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...

  3. LA 2965 Jurassic Remains (中途相遇法)

    Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...

  4. HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

    Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  5. 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  6. 高效算法——J 中途相遇法,求和

    ---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

  7. 【UVALive】2965 Jurassic Remains(中途相遇法)

    题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...

  8. uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)

    用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度. 这里用到一个很实用的技巧: 求长度为n的有序数组a中的数k的个数num? num=upper_bound(a,a+ ...

  9. LA 2965 中途相遇法

    题目链接:https://vjudge.net/problem/UVALive-2965 题意: 有很多字符串(24),选出一些字符串,要求这些字符串的字母都是偶数次: 分析: 暴力2^24也很大了, ...

随机推荐

  1. (转)git常见错误

      error: src refspec master does not match any. 引起该错误的原因是,目录中没有文件,空目录是不能提交上去的 error: insufficient pe ...

  2. HDU - 4027 Can you answer these queries?(线段树)

    给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...

  3. Vmware安装与使用

    1)双击击VMware Workstation启动安装 2)接下来Ctrl+N快捷键(或者点选菜单Flie->New virtual machine)来创建一个新的虚拟机. 3)Custom(a ...

  4. bash 统计在线时长最长的十个玩/统计一天内一直处于不活跃状态的玩家的百分比

    1.某游戏的客户端每隔5分钟会向服务端报告一次玩家的账户积分,如果两次报告的时间间隔不大于5分钟,认为该玩家在这5分钟内在线,假设报告数据的格式如下: IP                   Dat ...

  5. MFC自绘按钮的实现,按钮动态效果

    最近项目需要实现按钮的动态效果,多方学习,现在终于能实现一些功能了. 过程如下: 第一,新建一MFC对话框应用程序. 第二,删除自带按钮,并添加两个按钮,button1,button2,ID为IDB_ ...

  6. 聊聊、Nginx 参数合法性

    我们接着上篇文章来讲讲 ngx_get_options 函数. 这个函数就在 nginx.c 文件中,我们来看看. 参数 argc,argv 我们在前面的文章中都已经提到了,在这里我们看 ngx_ge ...

  7. Django创建

    Pycharm里面Django模块安装及项目创建和启动: Pycharm里面Django模块安装(也可以指定安装源): 创建Django项目: 注意切换到合适的目录进行安装 diango-admin ...

  8. iOS学习笔记41-Swift(一)基础部分

    一.Swift语言介绍 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题. Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种 ...

  9. 【bzoj3261】最大异或和 可持久化Trie树

    题目描述 给定一个非负整数序列 {a},初始长度为 N.       有M个操作,有以下两种操作类型:1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2.Q l r x:询问操 ...

  10. 浅谈android反调试之 转发端口

    反调试方案: 我们最通常使用的动态工具是IDA, IDA的动态调试端口默认为23946,我们可以通过/pro/net/tcp 查看android 系统所有TCP Socket 启动android_se ...