CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
1514: Packs
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 61 Solved: 4
[Submit][Status][Web Board]
Description
Give
you n packs, each of it has a value v and a weight w. Now you should
find some packs, and the total of these value is max, total of these
weight is equal to m.
Input
First line is a number T( T ≤ 5) represent the test cases.
Then for each set of cases, first line is n (1 ≤ n ≤ 40) and m (1 ≤ m
< 2^31), follow n line each is Wi (1 ≤ Wi < 2^31) and Vi (-2^31
< Vi < 2^31).
Output
Each case a line for max value.(Each set of inputs to ensure the solvability)
Sample Input
2
3 3
1 1
2 2
3 4
5 2
1 -5
1 -8
1 0
1 -2
1 5
Sample Output
4
5 注意:这里要求是满足总重量必须固定,而不是接近总重量。这就成了直接折半枚举,map大法就行了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const long long INF=99999999999999999LL;
const int EXP=1e-;
const int MS=; map<LL,LL> mp;
int n;
LL W; LL w[MS],v[MS]; void solve()
{
mp.clear();
int n1=n/;
for(int i=;i<(<<n1);i++)
{
LL sw=,sv=;
for(int j=;j<n1;j++)
{
if((i>>j)&)
{
sw+=w[j];
sv+=v[j];
}
}
mp[sw]=max(mp[sw],sv);
}
LL ans=-INF;
for(int i=;i< <<(n-n1);i++)
{
LL sw=,sv=;
for(int j=;j<(n-n1);j++)
{
if((i>>j)&)
{
sw+=w[n1+j];
sv+=v[n1+j];
}
}
if(mp.count(W-sw))
ans=max(ans,mp[W-sw]+sv);
}
printf("%lld\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%lld",&n,&W);
for(int i=;i<n;i++)
scanf("%lld%lld",&w[i],&v[i]);
solve();
}
return ;
}
如果是重量不大于 W ,那么就要折半枚举+二分查找。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const int INF=0x4fffffff;
const int EXP=1e-;
const int MS=; int n;
LL W;
LL w[MS],v[MS];
struct node
{
LL w,v;
bool operator <(const node &a) const //注意一定要加上const
{
return w<a.w||(w==a.w&&v<a.v);
}
}nodes[<<(MS/)]; LL find(LL w,int cnt)
{
int l=,r=cnt;
while(r-l>) // 左闭右开区间处理起来更方便。
{
int mid=(l+r)/;
if(nodes[mid].w<=w)
l=mid;
else
r=mid;
}
return nodes[l].v;
} void solve()
{
int n1=n/;
int cnt=;
for(int i=;i<(<<n1);i++)
{
LL sw=,sv=;
for(int j=;j<n1;j++)
{
if((i>>j)&)
{
sw+=w[j];
sv+=v[j];
}
}
nodes[cnt].w=sw;
nodes[cnt++].v=sv;
}
sort(nodes,nodes+cnt);
int last=;
for(int i=;i<cnt;i++)
{
if(nodes[last].v<nodes[i].v)
{
nodes[++last]=nodes[i];
}
}
cnt=last+;
LL ans=;
for(int i=;i< <<(n-n1);i++)
{
LL sw=,sv=;
for(int j=;j<(n-n1);j++)
{
if((i>>j)&)
{
sw+=w[n1+j];
sv+=v[n1+j];
}
}
if(sw<=W)
{
LL tv=find(W-sw,cnt);
ans=max(ans,sv+tv);
}
}
printf("%lld\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%lld",&n,&W);
for(int i=;i<n;i++)
scanf("%lld%lld",&w[i],&v[i]);
solve();
}
return ;
}
CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。的更多相关文章
- (容量超大)or(容量及价值)超大背包问题 ( 折半枚举 || 改变 dp 意义 )
题意 : 以下两个问题的物品都只能取有且只有一次 ① 给你 N 个物品,所有物品的价值总和不会超过 5000, 单个物品的价格就可达 10^10 ,背包容量为 B ② 给你 N (N ≤ 40 ) 个 ...
- poj3977(折半枚举+二分查找)
题目链接:https://vjudge.net/problem/POJ-3977 题意:给一个大小<=35的集合,找一个非空子集合,使得子集合元素和的绝对值最小,如果有多个这样的集合,找元素个数 ...
- Subset---poj3977(折半枚举+二分查找)
题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...
- Subset POJ - 3977(折半枚举+二分查找)
题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...
- 中南林业大学校赛 I 背包问题 ( 折半枚举 || 01背包递归写法 )
题目链接 题意 : 中文题 分析 : 价值和重量都太过于大,所以采用折半枚举的方法,详细可以看挑战的超大背包问题 由于 n <= 30 那么可以不必直接记录状态来优化,面对每个用例 直接采用递 ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
- POJ 2549 Sumsets(折半枚举+二分)
Sumsets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11946 Accepted: 3299 Descript ...
- Codeforces H. Prime Gift(折半枚举二分)
题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...
- POJ 2785 4 Values whose Sum is 0(折半枚举+二分)
4 Values whose Sum is 0 Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 25675 Accep ...
随机推荐
- cocos2d-x 2.2.5 安卓工程编译的问题
原址:http://www.cocoachina.com/bbs/read.php?tid=217124 新的cocos2d-x 2.2.5 在使用Eclipse的安卓NDK 9 的编译器进行编译的时 ...
- 使用sem_post信号量进行线程同步
写了一小段程序,测试一下线程同步的问题,如下: #include <stdio.h> #include <string.h> #include <semaphore.h& ...
- filter 过滤序列
class filter(object): """ filter(function or None, iterable) --> filter object Ret ...
- oracle学习 十 数据库的语句优化(持续更)
平时关注Oracle数据库的网友都知道,Oracle性能优化保证了Oracle数据库的健壮性.下面就此提出需要注意的两个原则. 原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的 ...
- MyEclipse中无法将SVN检出来的项目部署到tomcat中
自己遇到的小问题 : 要以web项目方式从svn上倒下来才可以部署到tomcat下检出步骤: myEclipse -->File-->new-->other-->svn--& ...
- HDU题目分类
基础题: 1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058. ...
- HDU 5702 Solving Order (水题,排序)
题意:给定几种不同的颜色和它的权值,按它的权值排序. 析:排序. 代码如下: #include <cstdio> #include <string> #include < ...
- Classifier4J的中文支持
Classifier4J是一个轻量级的分类工具,支持贝叶斯分类.向量空间模型.信息摘要等.然而它却不支持中文,异常信息大致如下: Exception in thread "main" ...
- Dubbo远程调用服务框架原理与示例
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
- CloudStack服务引擎配置(cloud-engine-service模块)
"?> <!--CloudStack服务引擎配置--> <beans xmlns="http://www.springframework.org/schem ...