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. python数据类型之集合(set)和其常用方法

    集合是一个无序的,不重复的数据组合 作用(集合的重点):1.去重,把一个列表变成集合就自动去重了2.关系测试,测试两组数据库之前的交集.差集.并集等关系 s = {1, 1, 2, 2, 3, 4, ...

  2. cf 1017C

    C. The Phone Number time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. [文章备份]Powershell Studio 2019 5.6.160 X64破解版 Crack

  4. BZOJ 5215: [Lydsy2017省队十连测]商店购物

    裸题 注意+特判 #include<cstdio> using namespace std; const int mod=1e9+7; int F[1000005],mi[10000005 ...

  5. 【Open-Falcon】Linux下安装Open-Falcon

    一.Open-Falcon组件简述 [Open-Falcon绘图相关组件] Agent:  部署在目标机器采集机器监控项 Transfer : 数据接收端,转发数据到后端Graph和Judge Gra ...

  6. zuul session 不一致的问题

    配置文件: #不加这句话导致session不一致zuul.routes.intelligentsia-authority.sensitiveHeaders = Authorization 过滤器里面 ...

  7. Install Oracle 11G Release 2 (11.2) on Centos Linux 7

    Install Oracle 11G Release 2 (11.2) on Centos Linux 7 This article presents how to install Oracle 11 ...

  8. 思路清奇:通过 JavaScript 获取移动设备的型号

    我们一般在浏览器里识别用户的访问设备都是通过 User Agent 这个字段来获取的,但是通过它我们只能获取一个大概的信息,比如你用的是 Mac 还是 Windows,用的是 iPhone 还是 iP ...

  9. tornado中文教程

    http://docs.pythontab.com/tornado/introduction-to-tornado/ch2.html#ch2-1 python的各种库的中文教程 http://docs ...

  10. 剑指offer 面试题38

    面试题38:数字在排序数组中出现的次数 题目:统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4. 主要的思路是进 ...