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. 思维题:UVa1334-Ancient Cipher

    Ancient Cipher Ancient Roman empire had a strong government system with various departments, includi ...

  2. C指针问题

    <!DOCTYPE html> 多级c指针传值问题 /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) / / Au ...

  3. webdriver高级应用- 测试HTML5语言实现的视频播放器

    能够获取HTML5语言实现的视频播放器,视频文件的地址.时长,控制播放器进行播放或暂停播放等操作. #encoding=utf-8 import unittest from selenium impo ...

  4. webdriver高级应用- 操作富文本框

    富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...

  5. 4003.基于Dijsktra算法的最短路径求解

    基于Dijsktra算法的最短路径求解 发布时间: 2018年11月26日 10:14   时间限制: 1000ms   内存限制: 128M 有趣的最短路...火候欠佳,目前还很难快速盲打出来,需继 ...

  6. 下载,配置环境变量,第一个demo

    一.在 http://www.oracle.com 下载java JDK 安装到自定义的地方. 二.配置环境变量:在我的电脑→高级系统设置→环境变量 ① 找到Path新增一个路径(该路径为JDK存放的 ...

  7. Linux Shell系列教程之(九)Shell判断 if else 用法

    本文是Linux Shell系列教程的第(九)篇,更多shell教程请看:Linux Shell系列教程 判断语句是每个语言都必不可少的关键语法,Shell命令当然也不例外.今天就给大家介绍下Shel ...

  8. Kafka介绍 (官方文档翻译)

    摘要:Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 这种动 ...

  9. [解决方案]Window 2008 R2 + IIS7.5 + VS2013 错误代码 0x80070002

    HTTP 错误 404.0 - Not Found 您要找的资源已被删除.已更名或暂时不可用.详细错误信息模块 IIS Web Core通知 MapRequest Handler处理程序 Static ...

  10. Java面试题之有没有有顺序的Map实现类,如果有,他们是怎么实现有序的?

    Hashmap和Hashtable 都不是有序的. TreeMap和LinkedHashmap都是有序的.(TreeMap默认是key升序,LinkedHashmap默认是数据插入顺序) TreeMa ...