中途相遇法 解决 超大背包问题 pack
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的更多相关文章
- 【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) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...
- uva 6757 Cup of Cowards(中途相遇法,貌似)
uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...
- LA 2965 Jurassic Remains (中途相遇法)
Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...
- HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
Difference Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...
- 高效算法——J 中途相遇法,求和
---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Su ...
- 【UVALive】2965 Jurassic Remains(中途相遇法)
题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...
- uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)
用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度. 这里用到一个很实用的技巧: 求长度为n的有序数组a中的数k的个数num? num=upper_bound(a,a+ ...
- LA 2965 中途相遇法
题目链接:https://vjudge.net/problem/UVALive-2965 题意: 有很多字符串(24),选出一些字符串,要求这些字符串的字母都是偶数次: 分析: 暴力2^24也很大了, ...
随机推荐
- 思维题:UVa1334-Ancient Cipher
Ancient Cipher Ancient Roman empire had a strong government system with various departments, includi ...
- C指针问题
<!DOCTYPE html> 多级c指针传值问题 /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) / / Au ...
- webdriver高级应用- 测试HTML5语言实现的视频播放器
能够获取HTML5语言实现的视频播放器,视频文件的地址.时长,控制播放器进行播放或暂停播放等操作. #encoding=utf-8 import unittest from selenium impo ...
- webdriver高级应用- 操作富文本框
富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...
- 4003.基于Dijsktra算法的最短路径求解
基于Dijsktra算法的最短路径求解 发布时间: 2018年11月26日 10:14 时间限制: 1000ms 内存限制: 128M 有趣的最短路...火候欠佳,目前还很难快速盲打出来,需继 ...
- 下载,配置环境变量,第一个demo
一.在 http://www.oracle.com 下载java JDK 安装到自定义的地方. 二.配置环境变量:在我的电脑→高级系统设置→环境变量 ① 找到Path新增一个路径(该路径为JDK存放的 ...
- Linux Shell系列教程之(九)Shell判断 if else 用法
本文是Linux Shell系列教程的第(九)篇,更多shell教程请看:Linux Shell系列教程 判断语句是每个语言都必不可少的关键语法,Shell命令当然也不例外.今天就给大家介绍下Shel ...
- Kafka介绍 (官方文档翻译)
摘要:Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 这种动 ...
- [解决方案]Window 2008 R2 + IIS7.5 + VS2013 错误代码 0x80070002
HTTP 错误 404.0 - Not Found 您要找的资源已被删除.已更名或暂时不可用.详细错误信息模块 IIS Web Core通知 MapRequest Handler处理程序 Static ...
- Java面试题之有没有有顺序的Map实现类,如果有,他们是怎么实现有序的?
Hashmap和Hashtable 都不是有序的. TreeMap和LinkedHashmap都是有序的.(TreeMap默认是key升序,LinkedHashmap默认是数据插入顺序) TreeMa ...